#if (FEATURE_MODE == 0)

/**
 @file sys_usw_sc_oam.c

 @date 2019-4-12

 @version v6.0

  This file contains se oam sys layer function implementation
*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "ctc_sc_oam.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_spool.h"
#include "ctc_hash.h"
#include "ctc_common.h"
#include "sys_usw_common.h"
#include "sys_usw_sc_oam.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dma.h"
#include "sys_usw_eunit.h"
#include "sys_usw_g8031.h"
#include "drv_api.h"
#include "sys_usw_chip.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"
#include "sys_usw_flexe.h"

/****************************************************************************
*
* Defines and Macros
*
*****************************************************************************/

#define SYS_SC_SPN_CODE      0x4B
#define SYS_SC_SPN_C_CODE    0xC
#define SYS_SC_TYPE_BAS      (0x1  << 2)
#define SYS_SC_TYPE_APS      (0x2  << 2)
#define SYS_SC_TYPE_CV       (0x11 << 2)
#define SYS_SC_TYPE_1DM      (0x12 << 2)
#define SYS_SC_TYPE_DMM      (0x13 << 2)
#define SYS_SC_TYPE_DMR      (0x14 << 2)
#define SYS_SC_TYPE_CS       (0x15 << 2)

#define SYS_SC_BYTE_OFFSET0  0
#define SYS_SC_BYTE_OFFSET1  1
#define SYS_SC_BYTE_OFFSET2  2
#define SYS_SC_BYTE_OFFSET3  3
#define SYS_SC_BYTE_OFFSET4  4
#define SYS_SC_BYTE_OFFSET5  5
#define SYS_SC_BYTE_OFFSET6  6
#define SYS_SC_BYTE_OFFSET7  7

#define SYS_SC_CLIENT_ID_NUM 120
#define SYS_APS_GRP_NUM  60
#define SYS_APS_GRP_SYNC_NUM 20
#define SYS_APS_GRP_READ_SIZE  16


#define SYS_DEFECT_TYPE_RX 1
#define SYS_DEFECT_TYPE_UPDATE 2
#define SYS_DEFECT_NUM ((SYS_SC_CLIENT_ID_NUM/5) -1)
#define SYS_SC_CPU_TX_MAX_BLOCK_NUM 16

/*set/cmd type to ECPU*/
enum sys_sc_oam_aps_prop_type_e
{
    SYS_SC_OAM_PROP_APS_INFO,          /**< [TMM] APS TX information, refer to ctc_sc_oam_aps_info_t */
    SYS_SC_OAM_PROP_APS_CMD           /**< [TMM] Set APS Command, refer to ctc_sc_oam_aps_cmd_t. Valid when set CTC_SC_OAM_PROP_HW_APS_SWTICH */
};
typedef enum sys_sc_oam_aps_prop_type_e sys_sc_oam_aps_prop_type_t;
enum sys_sc_oam_opf_type_e
{
    SYS_SC_OAM_OPF_TYPE_APS_GRP,
    SYS_SC_OAM_OPF_TYPE_MAX
};
typedef enum sys_sc_oam_opf_type_e sys_sc_oam_opf_type_t;

struct sys_sc_oam_client_s
{
    uint32 client_id;
    uint8 lchip;
};
typedef struct sys_sc_oam_client_s sys_sc_oam_client_t;


struct sys_sc_oam_mep_s
{
    uint32 client_id;   /* clientId */

    uint16 client_speed;
    uint8 bas_tx_period;
    uint8 rei_id;
    uint8 ber_id;
    ctc_sc_oam_ber_thrd_t ber_thrd;
    ctc_sc_oam_ber_thrd_t rei_thrd;

    uint16 aps_grp_id;/* aps group for state machine, alloc by opf*/
    ctc_sc_oam_aps_info_t aps_info;
    uint16 hw_client_id;
};
typedef struct sys_sc_oam_mep_s sys_sc_oam_mep_t;

struct sys_sc_oam_ber_s
{
    uint8 period;/*bas tx period*/
    ctc_sc_oam_ber_thrd_t  thrd;

    uint32  calc_key_len[0];

    ctc_spool_index_t index;
};
typedef struct sys_sc_oam_ber_s sys_sc_oam_ber_t;


struct sys_sc_oam_master_s
{
    sal_mutex_t* mutex;
    sal_mutex_t*   p_cb_mutex;
    ctc_hash_t* hash_mep;
    ctc_spool_t* spool_ber;
    ctc_spool_t* spool_rei;
    uint8  opf_type;
    uint32 rx_defect_vector[2];
    uint32 update_defect_vector[2];
    uint8 hw_aps;/*run APS state machine and do APS switch automatically*/
    g8031_aps_group_t aps_group[SYS_APS_GRP_NUM + 1]; /*group 0 is invalid*/
    uint8 aps_grp_cnt;
    uint32* mep_defect_bitmap;/*index by hw_client_id*/
};
typedef struct sys_sc_oam_master_s sys_sc_oam_master_t;
sys_sc_oam_master_t* g_sc_oam_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

extern int32
drv_usw_chip_read_ext(uint8 lchip, uint32 offset, uint32* p_value, uint32 length);

#define SYS_SC_OAM_INIT_CHECK(lchip)\
    do { \
        LCHIP_CHECK(lchip); \
        if (NULL == g_sc_oam_master[lchip]) \
        { \
            return CTC_E_NOT_INIT; \
        } \
    } while (0)

#define  SE_OAM_LOCK(lchip) \
    do { \
        if (g_sc_oam_master[lchip]->mutex) \
        { \
            sal_mutex_lock(g_sc_oam_master[lchip]->mutex); \
        } \
    } while (0)

#define  SE_OAM_UNLOCK(lchip) \
    do { \
        if (g_sc_oam_master[lchip]->mutex) \
        { \
            sal_mutex_unlock(g_sc_oam_master[lchip]->mutex); \
        } \
    } while (0)

#define  SE_OAM_CB_LOCK(lchip) \
            do { \
                if (g_sc_oam_master[lchip]->p_cb_mutex) \
                { \
                    sal_mutex_lock(g_sc_oam_master[lchip]->p_cb_mutex); \
                } \
            } while (0)

#define  SE_OAM_CB_UNLOCK(lchip) \
            do { \
                if (g_sc_oam_master[lchip]->p_cb_mutex) \
                { \
                    sal_mutex_unlock(g_sc_oam_master[lchip]->p_cb_mutex); \
                } \
            } while (0)

#define SYS_SC_OAM_DBG_OUT(level, FMT, ...) \
    do { \
        CTC_DEBUG_OUT(sc_oam, sc_oam, SC_OAM_SYS, level, FMT, ##__VA_ARGS__); \
    } while (0)

#define SYS_SC_OAM_BER(t, p, r) ((((uint64)t)*(p)*16*1024*64*(r)) / 10000000000000LL)
/****************************************************************************
*
* Function
*
***************************************************************************/
#if (SDK_WORK_PLATFORM == 0)
STATIC int32
_sys_usw_sc_oam_set_aps_hw(uint8 lchip, uint8 type, void* p_value1, void* p_value2)
{
#if defined E_UNIT && (FEATURE_MODE == 0)
    sys_sc_oam_set_aps_hw_t aps_to_ecpu;
    sal_memset(&aps_to_ecpu, 0, sizeof(sys_sc_oam_set_aps_hw_t));
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    switch (type)
    {
        case SYS_SC_OAM_PROP_APS_INFO:
            sal_memcpy(&aps_to_ecpu.aps_grop, (g8031_aps_group_t*)p_value1, sizeof(g8031_aps_group_t));

            break;
        case SYS_SC_OAM_PROP_APS_CMD:
            sal_memcpy(&aps_to_ecpu.aps_grop, (g8031_aps_group_t*)p_value1, sizeof(g8031_aps_group_t));
            sal_memcpy(&aps_to_ecpu.aps_pdu, (g8031_aps_pdu_t*)p_value2, sizeof(g8031_aps_pdu_t));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    aps_to_ecpu.type = type;

    /*write aps_to_ecpu  to ECPU*/
    if (MCHIP_EUNIT(lchip) && MCHIP_EUNIT(lchip)->set_cfg)
    {
        CTC_ERROR_RETURN(MCHIP_EUNIT(lchip)->set_cfg(lchip, SYS_EUNIT_CFG_G8031, (void*)&aps_to_ecpu));
    }
#endif
    return CTC_E_NONE;
}
#endif
STATIC uint8
_sys_usw_sc_oam_map_bas_period(uint8 lchip, uint8 period, uint8 is_unmap)
{
    uint32 value = 0;

    if (is_unmap)
    {
        if (32 == (period+1))
        {
            value = CTC_SC_OAM_PERIOD_512K_BLOCK;
        }
        else
        {
            value = ((period + 1) >> 1)&0xF;
        }
    }
    else
    {  /*multi of 16K*/
        if (CTC_SC_OAM_PERIOD_512K_BLOCK == period)
        {
            value = 32;
        }
        else
        {
            value = 1 << period;
        }
        value -= 1;
    }
    return value;
}


STATIC int32
_sys_usw_sc_oam_hash_traverse_cb(sys_sc_oam_mep_t* p_mep_db, void* p_user_data)
{
    sys_traverse_t* user_data = (sys_traverse_t*)p_user_data;
    uint32 cmd = 0;
    DsFlexEMepCfg_m ds;
    DsFlexEApsCfg_m ds_aps;
    uint32 active = 0;
    uint8 lchip = user_data->value3;
    char* period_desc[] = {"16K", "32K", "64K", "512K"};
    char speed[16] = {0};
    char tx_en[32] = {0};
    char* aps = "-";

    sal_sprintf(speed, "%d", p_mep_db->client_speed);
    sal_strcat(speed, "G");

    cmd = DRV_IOR(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
    cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds_aps));
    active = GetDsFlexEMepCfg(V, active_f,  &ds);
    if (GetDsFlexEMepCfg(V, basTxEn_f, &ds))
    {
        sal_strcat(tx_en, "BAS|");
    }
    if (GetDsFlexEApsCfg(V, apsTxEn_f, &ds_aps))
    {
        sal_strcat(tx_en, "APS|");
    }
    if (GetDsFlexEMepCfg(V, cvTxEn_f,  &ds))
    {
        sal_strcat(tx_en, "CV|");
    }
    if (GetDsFlexEMepCfg(V, _1dmEn_f,  &ds))
    {
        sal_strcat(tx_en, "1DM|");
    }
    if (GetDsFlexEMepCfg(V, dmmTxEn_f, &ds))
    {
        sal_strcat(tx_en, "DMM|");
    }
    if (GetDsFlexEMepCfg(V, csTxEn_f,  &ds))
    {
        sal_strcat(tx_en, "CS|");
    }
    if (sal_strlen(tx_en))
    {
        tx_en[sal_strlen(tx_en) - 1] = '\0';
    }
    else
    {
        tx_en[0] = '-';
    }
    if (p_mep_db->aps_info.aps_en)
    {
        aps = p_mep_db->aps_info.is_protection? "P" : "W";
    }

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-6d%-14u%-8d%-8s%-8s%-8s%-6s%-8s\n",
                       (user_data->value1++), p_mep_db->client_id, p_mep_db->hw_client_id, speed, active? "Y" : "N",
                        period_desc[p_mep_db->bas_tx_period], aps, tx_en);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_write_by_acc(uint8 lchip, uint32 index, void* ds, void* mask)
{
    ds_t CpuReq;
    uint32 cmd = 0;
    uint32 loop = 0;
    uint32 count = 0;
    uint32 cpuReqDone = 0;

    sal_memset(&CpuReq, 0 , sizeof(ds_t));
    /*1. clear result*/
    cmd = DRV_IOW(FlexEOamAccCpuResult_t, FlexEOamAccCpuResult_cpuReqDone_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &cpuReqDone));
    /*1. set request*/
    cmd = DRV_IOW(FlexEOamAccCpuReq_t, DRV_ENTRY_FLAG);
    SetFlexEOamAccCpuReq(V, reqValid_f, &CpuReq, 1);
    SetFlexEOamAccCpuReq(V, clientId_f, &CpuReq, index);
    SetFlexEOamAccCpuReq(A, wrData_f, &CpuReq, ds);
    SetFlexEOamAccCpuReq(A, wrDataMask_f, &CpuReq, mask);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &CpuReq));
     /*2. wait result done*/
     cmd = DRV_IOR(FlexEOamAccCpuResult_t, FlexEOamAccCpuResult_cpuReqDone_f);
    for (loop = 0; (loop < 2000) && !cpuReqDone; loop++)
    {
        for (count = 0; (count < 150) && !cpuReqDone; count++)
        {
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &cpuReqDone));
        }

        if (cpuReqDone)
        {
            return CTC_E_NONE;
        }
        sal_task_sleep(1);
    }
    return CTC_E_HW_BUSY;
}

STATIC int32
_sys_usw_sc_oam_lkup_cb(void* node_data, void* user_data)
{
    uint32 usr_client_id = 0;
    sys_sc_oam_mep_t* oam_node_data = (sys_sc_oam_mep_t*)node_data;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    usr_client_id = traversal_data->value2;

    if (oam_node_data->hw_client_id == usr_client_id)
    {
        traversal_data->value3  = oam_node_data->client_id;
        return CTC_E_EXIST;
    }
    return CTC_E_NONE;
}


STATIC sys_sc_oam_mep_t*
_sys_usw_sc_oam_lkup_by_asic_client(uint8 lchip, uint32  client_id)
{
    int32 ret = 0;
    sys_sc_oam_client_t oam_client;
    sys_traverse_t user_data;
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.value1 = lchip;
    user_data.value2 = client_id;
    ret = ctc_hash_traverse(g_sc_oam_master[lchip]->hash_mep, (hash_traversal_fn)_sys_usw_sc_oam_lkup_cb, (void*)&user_data);
    if (ret == CTC_E_EXIST)
    {
        oam_client.client_id = user_data.value3;
        return ctc_hash_lookup(g_sc_oam_master[lchip]->hash_mep , &oam_client);
    }
    return NULL;
}

STATIC sys_sc_oam_mep_t*
_sys_usw_sc_oam_lkup(uint8 lchip, uint32  client_id)
{
    sys_sc_oam_mep_t sys_mep;
    sal_memset(&sys_mep, 0, sizeof(sys_sc_oam_mep_t));
    sys_mep.client_id = client_id;
    return ctc_hash_lookup(g_sc_oam_master[lchip]->hash_mep , &sys_mep);
}

STATIC int32
_sys_usw_sc_oam_add_to_db(uint8 lchip, sys_sc_oam_mep_t* p_mep_db)
{
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (NULL == ctc_hash_insert(g_sc_oam_master[lchip]->hash_mep, p_mep_db))
    {
        return CTC_E_NO_MEMORY;
    }
    return CTC_E_NONE;
}


STATIC int32
_sys_usw_sc_oam_del_from_db(uint8 lchip, sys_sc_oam_mep_t* p_mep_db)
{
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (NULL == ctc_hash_remove(g_sc_oam_master[lchip]->hash_mep, p_mep_db))
    {
        return CTC_E_NOT_EXIST;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_add_ber_thrd(uint8 lchip, uint8* profile_id, sys_sc_oam_mep_t* p_mep_db, uint8 is_ber)
{
    sys_sc_oam_ber_t thrd;
    sys_sc_oam_ber_t* thrd_db = NULL;
    ctc_spool_t* spool = NULL;
    uint32 cmd = 0;
    ds_t ds;
    uint8 period = 0;
    ctc_sc_oam_ber_thrd_t tmp_thrd;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    period = _sys_usw_sc_oam_map_bas_period(lchip, p_mep_db->bas_tx_period, 0)+1;

    if (1 == is_ber)
    {
        sal_memcpy(&tmp_thrd, &p_mep_db->ber_thrd, sizeof(ctc_sc_oam_ber_thrd_t));
    }
    else
    {
        sal_memcpy(&tmp_thrd, &p_mep_db->rei_thrd, sizeof(ctc_sc_oam_ber_thrd_t));
    }

    sal_memset(&thrd, 0 , sizeof(sys_sc_oam_ber_t));
    thrd.period = period;
    thrd.thrd.ber_detect_time = tmp_thrd.ber_detect_time;
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "testPeriod               = %u\n", thrd.thrd.ber_detect_time);
    thrd.thrd.ddeg_set_thrd = SYS_SC_OAM_BER(thrd.thrd.ber_detect_time, period, tmp_thrd.ddeg_set_thrd);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dDegDetectThreshold      = %u\n", thrd.thrd.ddeg_set_thrd);
    thrd.thrd.ddeg_clear_thrd = SYS_SC_OAM_BER(thrd.thrd.ber_detect_time, period, tmp_thrd.ddeg_clear_thrd);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dDegDetectClearThreshold = %u\n", thrd.thrd.ddeg_clear_thrd);
    thrd.thrd.dexc_set_thrd = SYS_SC_OAM_BER(thrd.thrd.ber_detect_time, period, tmp_thrd.dexc_set_thrd);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dExcDetectThreshold      = %u\n", thrd.thrd.dexc_set_thrd);
    thrd.thrd.dexc_clear_thrd = SYS_SC_OAM_BER(thrd.thrd.ber_detect_time, period, tmp_thrd.dexc_clear_thrd);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dExcDetectClearThreshold = %u\n", thrd.thrd.dexc_clear_thrd);

    spool = (1 == is_ber)? g_sc_oam_master[lchip]->spool_ber : g_sc_oam_master[lchip]->spool_rei;
    CTC_ERROR_RETURN(ctc_spool_add(spool, &thrd, NULL, &thrd_db));
    if (NULL == thrd_db)
    {
        return CTC_E_NO_MEMORY;
    }
    /* BE/(T*period*16K*64) = BER */
    sal_memset(&ds, 0 , sizeof(ds_t));

    SetDsFlexEOamBerProfile(V, testPeriod_f,               &ds, thrd.thrd.ber_detect_time);
    SetDsFlexEOamBerProfile(V, dDegDetectThreshold_f,      &ds, thrd.thrd.ddeg_set_thrd);
    SetDsFlexEOamBerProfile(V, dDegDetectClearThreshold_f, &ds, thrd.thrd.ddeg_clear_thrd);
    SetDsFlexEOamBerProfile(V, dExcDetectThreshold_f,      &ds, thrd.thrd.dexc_set_thrd);
    SetDsFlexEOamBerProfile(V, dExcDetectClearThreshold_f, &ds, thrd.thrd.dexc_clear_thrd);

    cmd = DRV_IOW(is_ber? DsFlexEOamBerProfile_t : DsFlexEOamReiProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, thrd_db->index.index, cmd, &ds));
    *profile_id = thrd_db->index.index;
    if (1 == is_ber)
    {
        sal_memcpy(&( p_mep_db->ber_thrd), &thrd.thrd, sizeof(ctc_sc_oam_ber_thrd_t));
    }
    else
    {
        sal_memcpy(&( p_mep_db->rei_thrd), &thrd.thrd, sizeof(ctc_sc_oam_ber_thrd_t));
    }
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%s profile id           = %d\n", is_ber? "BER" : "REI", thrd_db->index.index);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_remove_ber_thrd(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, uint8 is_ber)
{
    sys_sc_oam_ber_t thrd;
    ctc_spool_t* spool = NULL;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&thrd, 0 , sizeof(sys_sc_oam_ber_t));
    sal_memcpy(&thrd.thrd, is_ber? &(p_mep_db->ber_thrd) : &(p_mep_db->rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
    thrd.period = _sys_usw_sc_oam_map_bas_period(lchip, p_mep_db->bas_tx_period, 0)+1;
    spool = (1 == is_ber)? g_sc_oam_master[lchip]->spool_ber : g_sc_oam_master[lchip]->spool_rei;
    CTC_ERROR_RETURN(ctc_spool_remove(spool, &thrd, NULL));
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_set_period(uint8 lchip, uint8 client_id, uint16 client_speed)
{
    uint32 cmd = 0;
    ds_t ds;
    uint32 value = 0;
    uint64 value64 = 0;

    /* oneSecCfg = speed/64*16K */
    /* e.g. speed = 5G, oneSecCfg = 5*10^9/64*16*1024 = 4768.4 */
    value64 = client_speed*1000000000LL;
    value = value64/(64*16*1024);
#if (SDK_WORK_PLATFORM == 1)
    value = 0;
#endif
    sal_memset(&ds, 0,sizeof(ds));
    SetDsFlexEMepCfg(V, oneSecCfg_f, &ds, value);
    cmd = DRV_IOW(DsFlexEMepCfg_t, DsFlexEMepCfg_oneSecCfg_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, client_id, cmd, &value));

    /* t(s) = 64*16K/speed, counterThrd = t*10^9/32ns */
    /* e.g. speed = 5G, t(s) = 64*16*1024/5*10^9, counterThrd = (64*16*1024/5*10^9)*10^9/32ns = 32768/5 = 6553.6 */
    value64 = (32768 << 8) / (client_speed);
    #ifdef EMULATION_ENV
    value64 = (32768 << 8) / (client_speed*5000);
    #endif
    value = ((value64>>8)&0xFFFFFFFF)-1;
    cmd = DRV_IOW(DsFlexEOamTxScanCfg_t, DsFlexEOamTxScanCfg_array_0_counterThrd_f + client_id%5);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, client_id/5, cmd, &value));
    value = value64&0xFF;
    cmd = DRV_IOW(DsFlexEOamTxScanCfg_t, DsFlexEOamTxScanCfg_array2_0_counterFracCfg_f + client_id%5);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, client_id/5, cmd, &value));
    return CTC_E_NONE;
}

#if defined E_UNIT && (FEATURE_MODE == 0)
STATIC int32
_sys_usw_sc_oam_create_aps_grp(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, ctc_sc_oam_aps_info_t* aps_info)/*only by working*/
{
    sys_usw_opf_t opf = {0};
    uint32 offset = 0;
    g8031_aps_group_t* aps_group = NULL;
    uint32 mac_id=0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if (CTC_IS_BIT_SET(aps_info->protection_type, 2))
    {
        return CTC_E_NOT_SUPPORT;
    }

    opf.pool_type = g_sc_oam_master[lchip]->opf_type;
    opf.pool_index = SYS_SC_OAM_OPF_TYPE_APS_GRP;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, 1, &offset));

    
    CTC_ERROR_RETURN(sys_usw_flexe_get_client_property(lchip, p_mep_db->client_id,
                                                                   CTC_FLEXE_CLIENT_PROP_BINDING_PORT, &dmps_port_info.gport));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&mac_id));

    p_mep_db->aps_grp_id = offset;
    aps_group = &(g_sc_oam_master[lchip]->aps_group[offset]);
    aps_group->aps_channel = CTC_IS_BIT_SET(aps_info->protection_type, 3);
    aps_group->bridge_permanent = !CTC_IS_BIT_SET(aps_info->protection_type, 2);
    aps_group->direction = CTC_IS_BIT_SET(aps_info->protection_type, 1);
    aps_group->is_revertive = CTC_IS_BIT_SET(aps_info->protection_type, 0);
    aps_group->requested_signal = aps_info->requested_signal;
    aps_group->bridged_signal = aps_info->bridged_signal;
    aps_group->last_state = aps_info->request_state;
    aps_group->current_state = aps_info->request_state;
    aps_group->wtr_timer = aps_info->wtr_timer? (aps_info->wtr_timer): 5;
    aps_group->aps_grp_id = p_mep_db->aps_grp_id;
    aps_group->active_path = p_mep_db->hw_client_id;
    aps_group->working_path = p_mep_db->hw_client_id;
    aps_group->lchip = lchip;
    aps_group->working_mac = mac_id;

    g_sc_oam_master[lchip]->aps_grp_cnt++;
    return CTC_E_NONE;
}
#endif
STATIC int32
_sys_usw_sc_oam_destroy_aps_grp(uint8 lchip, sys_sc_oam_mep_t* p_mep_db)/*only by working*/
{
    sys_usw_opf_t opf = {0};
    g8031_aps_group_t* aps_group = NULL;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    aps_group = &(g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id]);
    if (1 == aps_group->enable)
    {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need disable protectin MEP!\n");
        return CTC_E_IN_USE;
    }

    opf.pool_type = g_sc_oam_master[lchip]->opf_type;
    opf.pool_index = SYS_SC_OAM_OPF_TYPE_APS_GRP;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, 1, p_mep_db->aps_grp_id));
    sal_memset(aps_group, 0, sizeof(g8031_aps_group_t));
    if (g_sc_oam_master[lchip]->aps_grp_cnt > 0)
    {
        g_sc_oam_master[lchip]->aps_grp_cnt--;
    }
    return CTC_E_NONE;
}
#if defined E_UNIT && (FEATURE_MODE == 0)
STATIC int32
_sys_usw_sc_oam_add_to_aps_grp(uint8 lchip, sys_sc_oam_mep_t* p_mep_db)/*only by protection*/
{
    g8031_aps_group_t* aps_group = NULL;
    uint32 mac_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    aps_group = &(g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id]);
    if (1 == aps_group->protection_path_valid)
    {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Already have protection mep!\n");
        return CTC_E_EXIST;
    }

    CTC_ERROR_RETURN(sys_usw_flexe_get_client_property(lchip, p_mep_db->client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, &dmps_port_info.gport));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID_P, (void *)&mac_id));

    aps_group->protection_path = p_mep_db->hw_client_id;
    aps_group->protection_path_valid = 1;
    aps_group->enable = 1;
    aps_group->protection_mac = mac_id;

#if (SDK_WORK_PLATFORM == 0)
    CTC_ERROR_RETURN(_sys_usw_sc_oam_set_aps_hw(lchip, SYS_SC_OAM_PROP_APS_INFO, (void*)aps_group, NULL));
#endif

    return CTC_E_NONE;
}
#endif
STATIC int32
_sys_usw_sc_oam_remove_from_aps_grp(uint8 lchip, sys_sc_oam_mep_t* p_mep_db)/*only by protection*/
{
    g8031_aps_group_t* aps_group = NULL;
    aps_group = &(g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id]);

    aps_group->enable = 0;
    aps_group->protection_path_valid = 0;
    #if (SDK_WORK_PLATFORM == 0)
    CTC_ERROR_RETURN(_sys_usw_sc_oam_set_aps_hw(lchip,SYS_SC_OAM_PROP_APS_INFO,(void*)aps_group,NULL));
    #endif
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_aps_info(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, ctc_sc_oam_aps_info_t* aps_info)
{
    uint32 cmd = 0;
    ds_t ds;

#if defined E_UNIT && (FEATURE_MODE == 0)
    sys_sc_oam_mep_t* p_mep_db_w = NULL;
 #endif
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&ds, 0 , sizeof(ds_t));

    if (0 == g_sc_oam_master[lchip]->hw_aps)
    {
        cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
        SetDsFlexEApsCfg(V, apsState_f, &ds, aps_info->request_state);
        SetDsFlexEApsCfg(V, apsType_f, &ds, aps_info->protection_type);
        SetDsFlexEApsCfg(V, apsReqSig_f, &ds, aps_info->requested_signal);
        SetDsFlexEApsCfg(V, apsBridgeSig_f, &ds, aps_info->bridged_signal);
        cmd = DRV_IOW(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
        return CTC_E_NONE;
    }
    #if defined E_UNIT && (FEATURE_MODE == 0)
    /*1. enalbe APS*/
    if (1 == aps_info->aps_en)
    {
        if (1 == p_mep_db->aps_info.aps_en)
        {
            SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Already enable APS!\n");
            return CTC_E_INVALID_CONFIG;
        }
        /*1.1 current mep is working */
        if (0 == aps_info->is_protection)
        {
            CTC_ERROR_RETURN(_sys_usw_sc_oam_create_aps_grp(lchip, p_mep_db, aps_info));
        }
        /*1.2 current mep is protection */
        else
        {
            p_mep_db_w = _sys_usw_sc_oam_lkup(lchip, aps_info->w_client_id);
            if (NULL == p_mep_db_w)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Working MEP not exist!\n");
                return CTC_E_NOT_EXIST;
            }
            if (0 == p_mep_db_w->aps_info.aps_en)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Working MEP need enable APS!\n");
                return CTC_E_INVALID_CONFIG;
            }
            if (1 == p_mep_db_w->aps_info.is_protection)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need binding to working MEP!\n");
                return CTC_E_INVALID_CONFIG;
            }
            p_mep_db->aps_grp_id = p_mep_db_w->aps_grp_id;
            CTC_ERROR_RETURN(_sys_usw_sc_oam_add_to_aps_grp(lchip, p_mep_db));
        }
    }
    /*2. disalbe APS*/
    else
    {
        if (0 == p_mep_db->aps_info.aps_en)/*Already disable APS*/
        {
            return CTC_E_NONE;
        }
        /*2.1 current mep is working */
        if (0 == p_mep_db->aps_info.is_protection)
        {
            CTC_ERROR_RETURN(_sys_usw_sc_oam_destroy_aps_grp(lchip, p_mep_db));
        }
        /*2.2 current mep is protection */
        else
        {
            CTC_ERROR_RETURN(_sys_usw_sc_oam_remove_from_aps_grp(lchip, p_mep_db));
        }
    }
    sal_memcpy(&(p_mep_db->aps_info), aps_info, sizeof(ctc_sc_oam_aps_info_t));
#endif
    return CTC_E_NONE;
}
#if defined E_UNIT && (FEATURE_MODE == 0)
STATIC int32
_sys_usw_sc_oam_aps_cmd(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, uint32 cmd)
{
    g8031_aps_group_t* aps_group = NULL;
    g8031_aps_pdu_t pdu;
    ctc_sc_oam_event_t event;
    aps_group = &(g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id]);
    sal_memset(&event, 0, sizeof(ctc_sc_oam_event_t));

    if ((0 == p_mep_db->aps_info.aps_en) || (0 == aps_group->enable))
    {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need enable APS on working and protection MEP!\n");
        return CTC_E_NOT_READY;
    }
    sal_memset(&pdu, 0, sizeof(g8031_aps_pdu_t));

    switch (cmd)
    {
        case CTC_SC_OAM_APS_CMD_FS:
            pdu.req_state = G8031_FS;
            break;
        case CTC_SC_OAM_APS_CMD_MS_TO_P:
            pdu.req_state = G8031_MS_TO_P;
            break;
        case CTC_SC_OAM_APS_CMD_MS_TO_W:
            pdu.req_state = G8031_MS_TO_W;
            break;
        case CTC_SC_OAM_APS_CMD_EXER:
            pdu.req_state = G8031_EXER;
            break;
        case CTC_SC_OAM_APS_CMD_LO:
            pdu.req_state = G8031_LOCKOUT_OF_PROTECTION;
            break;
        case CTC_SC_OAM_APS_CMD_CLEAR:
            pdu.req_state = G8031_CLEAR;
            break;
        case CTC_SC_OAM_APS_CMD_SF:
            pdu.req_state = p_mep_db->aps_info.is_protection? G8031_SF_P : G8031_SF_W;
            break;
        case CTC_SC_OAM_APS_CMD_RSF:
            pdu.req_state = p_mep_db->aps_info.is_protection? G8031_P_RECOVERS_FROM_SF : G8031_W_RECOVERS_FROM_SF;
            break;
        case CTC_SC_OAM_APS_CMD_SD:
            pdu.req_state = p_mep_db->aps_info.is_protection? G8031_SD_P : G8031_SD_W;
            break;
        case CTC_SC_OAM_APS_CMD_RSD:
            pdu.req_state = p_mep_db->aps_info.is_protection? G8031_P_RECOVERS_FROM_SD : G8031_W_RECOVERS_FROM_SD;
            break;
        case CTC_SC_OAM_APS_CMD_FREEZE:
            aps_group->local_freeze = 1;
            break;
        case CTC_SC_OAM_APS_CMD_CLEAR_FREEZE:
            aps_group->local_freeze = 0;
            break;
        default:
            break;
    }
    if ((cmd != CTC_SC_OAM_APS_CMD_FREEZE) && (cmd != CTC_SC_OAM_APS_CMD_CLEAR_FREEZE))
    {
    #if (SDK_WORK_PLATFORM == 0)
        CTC_ERROR_RETURN(_sys_usw_sc_oam_set_aps_hw(lchip,SYS_SC_OAM_PROP_APS_CMD,(void*)aps_group,(void*)&pdu));
    #endif
    }

    return CTC_E_NONE;
}
#endif
STATIC int32
_sys_usw_sc_oam_add_to_asic(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, ctc_sc_oam_mep_t*  p_oam_mep,uint8 is_remove)
{
    uint32 cmd;
    ds_t ds;
    uint32 client_id = p_mep_db->hw_client_id;
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);


    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"OAM hard ware client id =%d\n",client_id);
    sal_memset(&ds, 0 , sizeof(ds_t));
    if (is_remove)
    {
        goto step2;
    }
    step1:
    SetDsFlexEMep(V, basRemotePeriod_f, &ds, p_oam_mep->bas_rx_period);
    SetDsFlexEMep(V, basRemoteIntervalCfg_f, &ds, _sys_usw_sc_oam_map_bas_period(lchip, p_oam_mep->bas_rx_period, 0));
    SetDsFlexEMep(V, basRemoteIntervalWhile_f, &ds, _sys_usw_sc_oam_map_bas_period(lchip, p_oam_mep->bas_rx_period, 0));
    if (p_oam_mep->bas_seq_mode)
    {
        SetDsFlexEMep(V, basRxSeq_f, &ds, p_oam_mep->bas_seq);
        SetDsFlexEMep(V, basTxSeq_f, &ds, p_oam_mep->bas_seq);
    }
    SetDsFlexEMep(V, localRdi_f, &ds, p_oam_mep->rdi? 1 : 0);
    cmd = DRV_IOW(DsFlexEMep_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    if (is_remove)
    {
        goto step3;
    }

    step2:
    sal_memset(&ds, 0 , sizeof(ds_t));
    if (0 == g_sc_oam_master[lchip]->hw_aps)
    {
        cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
        SetDsFlexEApsCfg(V, apsTxEn_f, &ds, 0);
        SetDsFlexEApsCfg(V, apsRxEn_f, &ds, 0);
        cmd = DRV_IOW(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    }
    sal_memset(&ds, 0 , sizeof(ds_t));
    SetDsFlexEMepCfg(V, active_f, &ds, CTC_FLAG_ISSET(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_MEP_EN)? 1 : 0);
    SetDsFlexEMepCfg(V, basRxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_BAS)? 1 : 0);
    SetDsFlexEMepCfg(V, basTxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_BAS)? 1 : 0);
    SetDsFlexEMepCfg(V, cvRxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_CV)? 1 : 0);
    SetDsFlexEMepCfg(V, cvTxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_CV)? 1 : 0);
    SetDsFlexEMepCfg(V, _1dmRxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_1DM)? 1 : 0);
    SetDsFlexEMepCfg(V, _1dmEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_1DM)? 1 : 0);
    SetDsFlexEMepCfg(V, dmRxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_2DM)? 1 : 0);
    SetDsFlexEMepCfg(V, dmmTxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_2DM)? 1 : 0);
    SetDsFlexEMepCfg(V, csRxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_CS)? 1 : 0);
    SetDsFlexEMepCfg(V, csTxEn_f, &ds, CTC_IS_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_CS)? 1 : 0);
    SetDsFlexEMepCfg(V, basIntervalCfg_f, &ds, _sys_usw_sc_oam_map_bas_period(lchip, p_oam_mep->bas_tx_period, 0));
    SetDsFlexEMepCfg(V, apsIntervalCfg_f, &ds, p_oam_mep->aps_interval? (p_oam_mep->aps_interval - 1) : 0);/*default 1s*/
    SetDsFlexEMepCfg(V, basSeqChkEn_f, &ds, 1);
    SetDsFlexEMepCfg(V, basSeqClearEn_f, &ds, 1);
    SetDsFlexEMepCfg(V, basRxSeqMode_f, &ds, p_oam_mep->bas_seq_mode? 0 : 1);
    SetDsFlexEMepCfg(V, basTxSeqMode_f, &ds, p_oam_mep->bas_seq_mode? 0 : 1);
    SetDsFlexEMepCfg(V, cvIntervalCfg_f, &ds, p_oam_mep->cv_interval? (p_oam_mep->cv_interval - 1) : 9);/*default 10s*/
    SetDsFlexEMepCfg(V, _1dmIntervalCfg_f, &ds, p_oam_mep->one_dm_interval? (p_oam_mep->one_dm_interval - 1) : 9);/*default 10s*/
    SetDsFlexEMepCfg(V, dmmIntervalCfg_f, &ds, p_oam_mep->two_dm_interval? (p_oam_mep->two_dm_interval - 1) : 0);/*default 1s*/
    SetDsFlexEMepCfg(V, csIntervalCfg_f, &ds, p_oam_mep->cs_interval? (p_oam_mep->cs_interval - 1) : 9);/*default 10s*/
    SetDsFlexEMepCfg(V, localCsLpi_f, &ds, p_oam_mep->cs_lpi? 1 : 0);
    SetDsFlexEMepCfg(V, localCsLf_f, &ds, p_oam_mep->cs_lf? 1 : 0);
    SetDsFlexEMepCfg(V, localCsRf_f, &ds, p_oam_mep->cs_rf? 1 : 0);

    SetDsFlexEMepCfg(V, csType_f, &ds, p_oam_mep->cs_type);
    SetDsFlexEMepCfg(V, dmDelayProfileId_f, &ds, 0);
    SetDsFlexEMepCfg(A, dapi_f, &ds, p_oam_mep->dapi);
    SetDsFlexEMepCfg(A, sapi_f, &ds, p_oam_mep->sapi);
    SetDsFlexEMepCfg(V, berProfileId_f, &ds, p_mep_db->ber_id);
    SetDsFlexEMepCfg(V, reiCheckEn_f, &ds, CTC_FLAG_ISSET(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_REI_CHK_EN));
    SetDsFlexEMepCfg(V, bipCalcEn_f, &ds, CTC_FLAG_ISSET(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_BIP_CHK_EN));
    SetDsFlexEMepCfg(V, reiProfileId_f, &ds, p_mep_db->rei_id);

    SetDsFlexEMepCfg(V, dlocChkRxNum_f, &ds, 3);
    SetDsFlexEMepCfg(V, dlocChkPeriodNum_f, &ds, 3);
    SetDsFlexEMepCfg(V, rdiAutoIndicateEn_f, &ds, 1);
    cmd = DRV_IOW(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    if (is_remove)
    {
        goto step1;
    }
    step3:

    CTC_ERROR_RETURN(_sys_usw_sc_oam_set_period(lchip, client_id, p_mep_db->client_speed));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_dump_config(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, ctc_sc_oam_mep_t* p_oam_mep)
{
    uint32 cmd;
    ds_t ds;
    uint32 client_id = p_mep_db->hw_client_id;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));

    if (GetDsFlexEMepCfg(V, active_f, &ds))
    {
        CTC_SET_FLAG(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_MEP_EN);
    }
    if (GetDsFlexEMepCfg(V, bipCalcEn_f, &ds))
    {
        CTC_SET_FLAG(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_BIP_CHK_EN);
    }
    if (GetDsFlexEMepCfg(V, reiCheckEn_f, &ds))
    {
        CTC_SET_FLAG(p_oam_mep->flag, CTC_SC_OAM_MEP_FLAG_REI_CHK_EN);
    }
    if (GetDsFlexEMepCfg(V, basRxEn_f, &ds))
    {
        CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_BAS);
    }
    if (GetDsFlexEMepCfg(V, basTxEn_f, &ds))
    {
        CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_BAS);
    }
    if (GetDsFlexEMepCfg(V, cvRxEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_CV);
    }
    if (GetDsFlexEMepCfg(V, cvTxEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_CV);
    }
    if (GetDsFlexEMepCfg(V, _1dmRxEn_f, &ds))
    {
        CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_1DM);
    }
    if (GetDsFlexEMepCfg(V, _1dmEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_1DM);
    }
    if (GetDsFlexEMepCfg(V, dmRxEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_2DM);
    }
    if (GetDsFlexEMepCfg(V, dmmTxEn_f, &ds))
    {
        CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_2DM);
    }
    if (GetDsFlexEMepCfg(V, csRxEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_CS);
    }
    if (GetDsFlexEMepCfg(V, csTxEn_f,  &ds))
    {
        CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_CS);
    }

    p_oam_mep->aps_interval    = GetDsFlexEMepCfg(V, apsIntervalCfg_f,  &ds) + 1;
    p_oam_mep->cv_interval     = GetDsFlexEMepCfg(V, cvIntervalCfg_f,   &ds) + 1;
    p_oam_mep->one_dm_interval = GetDsFlexEMepCfg(V, _1dmIntervalCfg_f, &ds) + 1;
    p_oam_mep->two_dm_interval = GetDsFlexEMepCfg(V, dmmIntervalCfg_f,  &ds) + 1;
    p_oam_mep->cs_interval     = GetDsFlexEMepCfg(V, csIntervalCfg_f,   &ds) + 1;
    p_oam_mep->cs_type         = GetDsFlexEMepCfg(V, csType_f,          &ds);
    p_oam_mep->bas_seq_mode    = GetDsFlexEMepCfg(V, basRxSeqMode_f,          &ds)? 0 : 1;
    p_oam_mep->cs_lpi          = GetDsFlexEMepCfg(V, localCsLpi_f,          &ds);
    p_oam_mep->cs_lf           = GetDsFlexEMepCfg(V, localCsLf_f,          &ds);
    p_oam_mep->cs_rf           = GetDsFlexEMepCfg(V, localCsRf_f,          &ds);
    GetDsFlexEMepCfg(A, dapi_f, &ds, p_oam_mep->dapi);
    GetDsFlexEMepCfg(A, sapi_f, &ds, p_oam_mep->sapi);
    p_oam_mep->bas_tx_period = p_mep_db->bas_tx_period;
    sal_memcpy(&(p_oam_mep->ber_thrd), &(p_mep_db->ber_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
    sal_memcpy(&(p_oam_mep->rei_thrd), &(p_mep_db->rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEMep_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    p_oam_mep->bas_rx_period = GetDsFlexEMep(V, basRemotePeriod_f,  &ds);
    if (p_oam_mep->bas_seq_mode)
    {
        p_oam_mep->bas_seq = GetDsFlexEMep(V, basRxSeq_f, &ds);
    }
    p_oam_mep->rdi             = GetDsFlexEMep(V, localRdi_f,          &ds);
    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    if (g_sc_oam_master[lchip]->hw_aps)
    {
        if (p_mep_db->aps_info.aps_en)
        {
            CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_APS);
            CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_APS);
        }
    }
    else
    {
        if (GetDsFlexEApsCfg(V, apsTxEn_f, &ds))
        {
            CTC_BIT_SET(p_oam_mep->tx_en_bmp, CTC_SC_OAM_TYPE_APS);
        }
        if (GetDsFlexEApsCfg(V, apsRxEn_f, &ds))
        {
            CTC_BIT_SET(p_oam_mep->rx_en_bmp, CTC_SC_OAM_TYPE_APS);
        }
    }
    p_oam_mep->client_speed = p_mep_db->client_speed;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_dump_state(uint8 lchip, sys_sc_oam_mep_t* p_mep_db, ctc_sc_oam_mep_info_t* p_oam_mep_info)
{
    uint32 cmd;
    ds_t ds;
    uint32 client_id = p_mep_db->hw_client_id;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    p_oam_mep_info->cs_lpi = GetDsFlexEMepCfg(V, localCsLpi_f, &ds);
    p_oam_mep_info->cs_lf = GetDsFlexEMepCfg(V, localCsLf_f, &ds);
    p_oam_mep_info->cs_rf = GetDsFlexEMepCfg(V, localCsRf_f, &ds);

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEMep_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    p_oam_mep_info->first_rx = GetDsFlexEMep(V, firstRxBlock_f, &ds);
    p_oam_mep_info->rdi = GetDsFlexEMep(V, localRdi_f, &ds);
    p_oam_mep_info->dloc = GetDsFlexEMep(V, dLoc_f, &ds);
    p_oam_mep_info->ddeg = GetDsFlexEMep(V, dDeg_f, &ds);
    p_oam_mep_info->dexc = GetDsFlexEMep(V, dExc_f, &ds);
    p_oam_mep_info->sapi_chk = GetDsFlexEMep(V, dSapiMismatch_f, &ds);
    p_oam_mep_info->dapi_chk = GetDsFlexEMep(V, dDapiMismatch_f, &ds);
    p_oam_mep_info->cs_type_chk = GetDsFlexEMep(V, dCsTypeMismatch_f, &ds);
    p_oam_mep_info->remote_cs_lpi = GetDsFlexEMep(V, remoteCsLpi_f, &ds);
    p_oam_mep_info->remote_cs_lf = GetDsFlexEMep(V, remoteCsLf_f, &ds);
    p_oam_mep_info->remote_cs_rf = GetDsFlexEMep(V, remoteCsRf_f, &ds);
    p_oam_mep_info->remote_rdi = GetDsFlexEMep(V, lastRxRdi_f, &ds);
    p_oam_mep_info->ddeg_rei = GetDsFlexEMep(V, dReiDeg_f, &ds);
    p_oam_mep_info->dexc_rei = GetDsFlexEMep(V, dReiExc_f, &ds);
    p_oam_mep_info->seq_chk = (GetDsFlexEMep(V, dBasSeqMismatch_f, &ds) || GetDsFlexEMep(V, dApsSeqMismatch_f, &ds)
    || GetDsFlexEMep(V, dCsSeqMismacth_f, &ds) || GetDsFlexEMep(V, dCvSeqMismacth_f, &ds));
    p_oam_mep_info->remote_period_chk = GetDsFlexEMep(V, dBasRemotePeriod_f, &ds);
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_sc_oam_set_ber_thrd(uint8 lchip, sys_sc_oam_mep_t* p_mep_db,void* p_value,uint8 is_ber,uint32 bas_tx_period)
{
    uint8 profile_id = 0;
    uint32 field_value = 0;
    uint32 cmd =0;
    sys_sc_oam_mep_t mep_db_tmp;

    sal_memcpy(&mep_db_tmp, p_mep_db, sizeof(sys_sc_oam_mep_t));
    is_ber?  sal_memcpy(&(mep_db_tmp.ber_thrd), p_value, sizeof(ctc_sc_oam_ber_thrd_t)):
    sal_memcpy(&(mep_db_tmp.rei_thrd), p_value, sizeof(ctc_sc_oam_ber_thrd_t));
    mep_db_tmp.bas_tx_period = bas_tx_period;
    CTC_ERROR_RETURN(_sys_usw_sc_oam_add_ber_thrd(lchip, (uint8*)&profile_id, &mep_db_tmp, is_ber));
    cmd = DRV_IOW(DsFlexEMepCfg_t, is_ber? DsFlexEMepCfg_berProfileId_f : DsFlexEMepCfg_reiProfileId_f);
    field_value = profile_id;
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &field_value));
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db, is_ber);
    if (is_ber)
    {
        sal_memcpy(&( p_mep_db->ber_thrd), &mep_db_tmp.ber_thrd, sizeof(ctc_sc_oam_ber_thrd_t));
        p_mep_db->ber_id = profile_id;
    }
    else
    {
        sal_memcpy(&(p_mep_db->rei_thrd), &mep_db_tmp.rei_thrd, sizeof(ctc_sc_oam_ber_thrd_t));
        p_mep_db->rei_id = profile_id;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_set_to_asic(uint8 lchip, sys_sc_oam_mep_t* p_mep_db,  ctc_sc_oam_mep_prop_t* p_mep_prop)
{
    uint32 cmd;
    ds_t mep_cfg;
    ds_t mep;
    ds_t mep_mask;
    ds_t ds;
    uint32 client_id = 0;
    uint32 value =0;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&mep_cfg, 0 , sizeof(ds_t));
    sal_memset(&mep, 0 , sizeof(ds_t));
    sal_memset(&mep_mask, 0xFF, sizeof(ds_t));
    sal_memset(&ds, 0 , sizeof(ds_t));

    client_id = p_mep_db->hw_client_id;

    cmd = DRV_IOR(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &mep_cfg));
    switch (p_mep_prop->prop_type)
    {
        case CTC_SC_OAM_MEP_PROP_MEP_EN:
            SetDsFlexEMepCfg(V, active_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_CLIENT_SPEED:
            CTC_ERROR_RETURN(_sys_usw_sc_oam_set_period(lchip, client_id, p_mep_prop->update_value));
            p_mep_db->client_speed = p_mep_prop->update_value;
            return CTC_E_NONE;
            break;
        case CTC_SC_OAM_MEP_PROP_RX_EN_BMP:
            SetDsFlexEMepCfg(V, basRxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_BAS)? 1 : 0);
            SetDsFlexEMepCfg(V, cvRxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_CV)? 1 : 0);
            SetDsFlexEMepCfg(V, _1dmRxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_1DM)? 1 : 0);
            SetDsFlexEMepCfg(V, dmRxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_2DM)? 1 : 0);
            SetDsFlexEMepCfg(V, csRxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_CS)? 1 : 0);
            if (0 == g_sc_oam_master[lchip]->hw_aps)
            {
                cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
                SetDsFlexEApsCfg(V, apsRxEn_f, &ds, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_APS)? 1 : 0);
                cmd = DRV_IOW(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
            }
            else if(CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_APS))
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " HW APS need to enable through APS_INFO!\n");
                return CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_TX_EN_BMP:
            SetDsFlexEMepCfg(V, basTxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_BAS)? 1 : 0);
            SetDsFlexEMepCfg(V, cvTxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_CV)? 1 : 0);
            SetDsFlexEMepCfg(V, _1dmEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_1DM)? 1 : 0);
            SetDsFlexEMepCfg(V, dmmTxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_2DM)? 1 : 0);
            SetDsFlexEMepCfg(V, csTxEn_f, &mep_cfg, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_CS)? 1 : 0);
            if (0 == g_sc_oam_master[lchip]->hw_aps)
            {
                cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
                SetDsFlexEApsCfg(V, apsTxEn_f, &ds, CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_APS)? 1 : 0);
                cmd = DRV_IOW(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
            }
            else if(CTC_IS_BIT_SET(p_mep_prop->update_value, CTC_SC_OAM_TYPE_APS))
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " HW APS need to enable through APS_INFO!\n");
                return CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_BIP_CHK_EN:
            SetDsFlexEMepCfg(V, bipCalcEn_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_REI_CHK_EN:
            SetDsFlexEMepCfg(V, reiCheckEn_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_RX_PERIOD:
            SetDsFlexEMep(V, basRemotePeriod_f, &mep, p_mep_prop->update_value);
            SetDsFlexEMep(V, basRemotePeriod_f, &mep_mask, 0);
            SetDsFlexEMep(V, basRemoteIntervalCfg_f, &mep, _sys_usw_sc_oam_map_bas_period(lchip, p_mep_prop->update_value, 0));
            SetDsFlexEMep(V, basRemoteIntervalCfg_f, &mep_mask, 0);
            SetDsFlexEMep(V, basRemoteIntervalWhile_f, &mep, _sys_usw_sc_oam_map_bas_period(lchip, p_mep_prop->update_value, 0));
            SetDsFlexEMep(V, basRemoteIntervalWhile_f, &mep_mask, 0);
            CTC_ERROR_RETURN(_sys_usw_sc_oam_write_by_acc(lchip, client_id, &mep, &mep_mask));
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_TX_PERIOD:
            {
                value = _sys_usw_sc_oam_map_bas_period(lchip, p_mep_prop->update_value, 0);

                cmd = DRV_IOW(DsFlexEMepCfg_t,  DsFlexEMepCfg_basIntervalCfg_f );
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, client_id, cmd, &value));
                CTC_ERROR_RETURN(_sys_usw_sc_oam_set_ber_thrd(lchip, p_mep_db, (void*)&p_mep_db->rei_thrd, 0, p_mep_prop->update_value));
                CTC_ERROR_RETURN(_sys_usw_sc_oam_set_ber_thrd(lchip, p_mep_db, (void*)&p_mep_db->ber_thrd, 1, p_mep_prop->update_value));
                p_mep_db->bas_tx_period = p_mep_prop->update_value;
                return CTC_E_NONE;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ_MODE:
            SetDsFlexEMepCfg(V, basRxSeqMode_f, &mep_cfg, p_mep_prop->update_value? 0 : 1);
            SetDsFlexEMepCfg(V, basTxSeqMode_f, &mep_cfg, p_mep_prop->update_value? 0 : 1);
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ:
            SetDsFlexEMep(V, basRxSeq_f, &mep, p_mep_prop->update_value);
            SetDsFlexEMep(V, basRxSeq_f, &mep_mask, 0);
            SetDsFlexEMep(V, basTxSeq_f, &mep, p_mep_prop->update_value);
            SetDsFlexEMep(V, basTxSeq_f, &mep_mask, 0);
            CTC_ERROR_RETURN(_sys_usw_sc_oam_write_by_acc(lchip, client_id, &mep, &mep_mask));
            break;
        case CTC_SC_OAM_MEP_PROP_BER_THRD:
            {
               CTC_ERROR_RETURN(_sys_usw_sc_oam_set_ber_thrd(lchip,p_mep_db,p_mep_prop->p_update_value,1,p_mep_db->bas_tx_period));
               return CTC_E_NONE;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_REI_THRD:
            {
               CTC_ERROR_RETURN(_sys_usw_sc_oam_set_ber_thrd(lchip,p_mep_db,p_mep_prop->p_update_value,0,p_mep_db->bas_tx_period));
               return CTC_E_NONE;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_CS_LPI:
            SetDsFlexEMepCfg(V, localCsLpi_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_CS_LF:
            SetDsFlexEMepCfg(V, localCsLf_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_CS_RF:
            SetDsFlexEMepCfg(V, localCsRf_f, &mep_cfg, p_mep_prop->update_value? 1 : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_RDI:
            SetDsFlexEMep(V, localRdi_f, &mep, p_mep_prop->update_value? 1 : 0);
            SetDsFlexEMep(V, localRdi_f, &mep_mask, 0);
            CTC_ERROR_RETURN(_sys_usw_sc_oam_write_by_acc(lchip, client_id, &mep, &mep_mask));
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INTERVAL:
           SetDsFlexEMepCfg(V, apsIntervalCfg_f, &mep_cfg, p_mep_prop->update_value? (p_mep_prop->update_value - 1) : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_APS_TX_RAPID:
            {
                sal_memset(&ds, 0 , sizeof(ds_t));
                cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
                SetDsFlexEApsCfg(V, apsTriggerCnt_f, &ds, p_mep_prop->update_value);
                cmd = DRV_IOW(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
                return CTC_E_NONE;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INFO:
             CTC_ERROR_RETURN(_sys_usw_sc_oam_aps_info(lchip, p_mep_db, (ctc_sc_oam_aps_info_t*)(p_mep_prop->p_update_value)));
            return CTC_E_NONE;
        case CTC_SC_OAM_MEP_PROP_APS_CMD:
            #if defined E_UNIT && (FEATURE_MODE == 0)
            CTC_ERROR_RETURN(_sys_usw_sc_oam_aps_cmd(lchip, p_mep_db, p_mep_prop->update_value));
            #endif
            return CTC_E_NONE;
        case CTC_SC_OAM_MEP_PROP_CV_INTERVAL:
            SetDsFlexEMepCfg(V, cvIntervalCfg_f, &mep_cfg, p_mep_prop->update_value? (p_mep_prop->update_value - 1) : 9);
            break;
        case CTC_SC_OAM_MEP_PROP_SAPI:
            SetDsFlexEMepCfg(A, sapi_f, &mep_cfg, p_mep_prop->p_update_value);
            break;
        case CTC_SC_OAM_MEP_PROP_DAPI:
            SetDsFlexEMepCfg(A, dapi_f, &mep_cfg, p_mep_prop->p_update_value);
            break;
        case CTC_SC_OAM_MEP_PROP_1DM_INTERVAL:
                SetDsFlexEMepCfg(V, _1dmIntervalCfg_f, &mep_cfg, p_mep_prop->update_value? (p_mep_prop->update_value - 1) : 9);
            break;
        case CTC_SC_OAM_MEP_PROP_2DM_INTERVAL:
                SetDsFlexEMepCfg(V, dmmIntervalCfg_f, &mep_cfg, p_mep_prop->update_value? (p_mep_prop->update_value - 1) : 0);
            break;
        case CTC_SC_OAM_MEP_PROP_CS_INTERVAL:
                SetDsFlexEMepCfg(V, csIntervalCfg_f, &mep_cfg, p_mep_prop->update_value? (p_mep_prop->update_value - 1) : 9);
            break;
        case CTC_SC_OAM_MEP_PROP_CS_TYPE:
            SetDsFlexEMepCfg(V, csType_f, &mep_cfg, p_mep_prop->update_value);
            break;
        default:
            return CTC_E_INVALID_PARAM;
            break;
    }

    cmd = DRV_IOW(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &mep_cfg));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_get_from_asic(uint8 lchip, sys_sc_oam_mep_t* p_mep_db,  ctc_sc_oam_mep_prop_t* p_mep_prop)
{
    ds_t ds;
    uint32 cmd =0;
    ctc_sc_oam_mep_t oam_mep;
    ctc_sc_oam_aps_info_t* tmp_info = NULL;
    ctc_sc_oam_ber_cnt_t* ber_info = NULL;
    sal_memset(&oam_mep, 0, sizeof(ctc_sc_oam_mep_t));
    sal_memset(&ds, 0 , sizeof(ds_t));
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_ERROR_RETURN(_sys_usw_sc_oam_dump_config(lchip, p_mep_db, &oam_mep));

    switch (p_mep_prop->prop_type)
    {
        case CTC_SC_OAM_MEP_PROP_MEP_EN:
            p_mep_prop->update_value = CTC_FLAG_ISSET(oam_mep.flag, CTC_SC_OAM_MEP_FLAG_MEP_EN);
            break;
        case CTC_SC_OAM_MEP_PROP_CLIENT_SPEED:
            p_mep_prop->update_value = p_mep_db->client_speed;
            break;
        case CTC_SC_OAM_MEP_PROP_RX_EN_BMP:
            p_mep_prop->update_value = oam_mep.rx_en_bmp;
            break;
        case CTC_SC_OAM_MEP_PROP_TX_EN_BMP:
            p_mep_prop->update_value = oam_mep.tx_en_bmp;
            break;
        case CTC_SC_OAM_MEP_PROP_BIP_CHK_EN:
            p_mep_prop->update_value = CTC_FLAG_ISSET(oam_mep.flag, CTC_SC_OAM_MEP_FLAG_BIP_CHK_EN);
            break;
        case CTC_SC_OAM_MEP_PROP_REI_CHK_EN:
            p_mep_prop->update_value = CTC_FLAG_ISSET(oam_mep.flag, CTC_SC_OAM_MEP_FLAG_REI_CHK_EN);
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_RX_PERIOD:
            p_mep_prop->update_value = oam_mep.bas_rx_period;
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_TX_PERIOD:
            p_mep_prop->update_value = oam_mep.bas_tx_period;
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ_MODE:
            p_mep_prop->update_value = oam_mep.bas_seq_mode;
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ:
            p_mep_prop->update_value = oam_mep.bas_seq;
            break;
        case CTC_SC_OAM_MEP_PROP_BER_THRD:
            if (NULL == p_mep_prop->p_update_value)
            {
                return CTC_E_INVALID_PTR;
            }
            sal_memcpy(p_mep_prop->p_update_value, &(oam_mep.ber_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
            break;
        case CTC_SC_OAM_MEP_PROP_REI_THRD:
            if (NULL == p_mep_prop->p_update_value)
            {
                return CTC_E_INVALID_PTR;
            }
            sal_memcpy(p_mep_prop->p_update_value, &(oam_mep.rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
            break;
        case CTC_SC_OAM_MEP_PROP_CS_LPI:
            p_mep_prop->update_value = oam_mep.cs_lpi;
            break;
        case CTC_SC_OAM_MEP_PROP_CS_LF:
            p_mep_prop->update_value = oam_mep.cs_lf;
            break;
        case CTC_SC_OAM_MEP_PROP_CS_RF:
            p_mep_prop->update_value = oam_mep.cs_rf;
            break;
        case CTC_SC_OAM_MEP_PROP_RDI:
            p_mep_prop->update_value = oam_mep.rdi;
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INTERVAL:
            p_mep_prop->update_value = oam_mep.aps_interval;
            break;
        case CTC_SC_OAM_MEP_PROP_CV_INTERVAL:
            p_mep_prop->update_value = oam_mep.cv_interval;
            break;
        case CTC_SC_OAM_MEP_PROP_SAPI:
            if (NULL == p_mep_prop->p_update_value)
            {
                return CTC_E_INVALID_PTR;
            }
            sal_memcpy(p_mep_prop->p_update_value, oam_mep.sapi, 16);
            break;
        case CTC_SC_OAM_MEP_PROP_DAPI:
            if (NULL == p_mep_prop->p_update_value)
            {
                return CTC_E_INVALID_PTR;
            }
            sal_memcpy(p_mep_prop->p_update_value, oam_mep.dapi, 16);
            break;
        case CTC_SC_OAM_MEP_PROP_1DM_INTERVAL:
            p_mep_prop->update_value = oam_mep.one_dm_interval;
            break;
        case CTC_SC_OAM_MEP_PROP_2DM_INTERVAL:
            p_mep_prop->update_value = oam_mep.two_dm_interval;
            break;
        case CTC_SC_OAM_MEP_PROP_CS_INTERVAL:
            p_mep_prop->update_value = oam_mep.cs_interval;
            break;
        case CTC_SC_OAM_MEP_PROP_CS_TYPE:
            p_mep_prop->update_value = oam_mep.cs_type;
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INFO:
            if (NULL == p_mep_prop->p_update_value)
            {
                return CTC_E_INVALID_PTR;
            }
            tmp_info = (ctc_sc_oam_aps_info_t*)p_mep_prop->p_update_value;
            if ( g_sc_oam_master[lchip]->hw_aps)
            {
                sal_memcpy(tmp_info, &(p_mep_db->aps_info), sizeof(ctc_sc_oam_aps_info_t));
                tmp_info->requested_signal = g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].requested_signal;
                tmp_info->bridged_signal = g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].bridged_signal;
                tmp_info->current_state = g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].current_state;
                tmp_info->last_state = g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].last_state;
                tmp_info->request_state= g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].current_event;
            }
            else
            {
                cmd = DRV_IOR(DsFlexEApsCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
                tmp_info->request_state= GetDsFlexEApsCfg(V, apsState_f, &ds);
                tmp_info->protection_type = GetDsFlexEApsCfg(V, apsType_f, &ds);
                tmp_info->requested_signal = GetDsFlexEApsCfg(V, apsReqSig_f, &ds);
                tmp_info->bridged_signal = GetDsFlexEApsCfg(V, apsBridgeSig_f, &ds);
            }
            break;
        case CTC_SC_OAM_MEP_PROP_APS_PROTECTION_EN:
            break;
        case CTC_SC_OAM_MEP_PROP_BER_CNT:
            ber_info = (ctc_sc_oam_ber_cnt_t*)p_mep_prop->p_update_value;
            cmd = DRV_IOR(DsFlexEOamBerStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
            ber_info->bip_cnt = GetDsFlexEOamBerStats(V, berSumStats_f, &ds);

            cmd = DRV_IOR(DsFlexEOamReiStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->hw_client_id, cmd, &ds));
            ber_info->rei_cnt = GetDsFlexEOamReiStats(V, berSumStats_f, &ds);
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}


STATIC int32
_sys_usw_sc_oam_register_init(uint8 lchip)
{
    uint32 cmd = 0;
    ds_t ds;
    uint32 value = 0;
    uint32 defect[2]  = {0xFFFFFFFE, 0xFFFFFFFF};
    uint32 index=0;
    sys_usw_dma_export_map_t dma_map;

    sal_memset(&dma_map, 0, sizeof(sys_usw_dma_export_map_t));

    value = 1;
    cmd = DRV_IOW(SpnOamInit_t, SpnOamInit_init_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOR(SpnOamInitDone_t, SpnOamInitDone_initDone_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"SpnOaminitDone is %d\n", value);

    value=0;
    cmd = DRV_IOW(RefDivSpnOamTxPulse_t, RefDivSpnOamTxPulse_cfgResetDivSpnOamTxPulse_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamParserCtl(V, spnCodeType_f, &ds, SYS_SC_SPN_CODE);
    SetFlexEOamParserCtl(V, cCodeCheckValue_f, &ds, SYS_SC_SPN_C_CODE);
    SetFlexEOamParserCtl(V, basBlockType_f, &ds, SYS_SC_TYPE_BAS);
    SetFlexEOamParserCtl(V, apsBlockType_f, &ds, SYS_SC_TYPE_APS);
    SetFlexEOamParserCtl(V, cvBlockType_f, &ds, SYS_SC_TYPE_CV);
    SetFlexEOamParserCtl(V, oneDmBlockType_f, &ds, SYS_SC_TYPE_1DM);
    SetFlexEOamParserCtl(V, dmmBlockType_f, &ds, SYS_SC_TYPE_DMM);
    SetFlexEOamParserCtl(V, dmrBlockType_f, &ds, SYS_SC_TYPE_DMR);
    SetFlexEOamParserCtl(V, csBlockType_f, &ds, SYS_SC_TYPE_CS);
    SetFlexEOamParserCtl(V, apsSeqCheckEn_f, &ds, 1);
    SetFlexEOamParserCtl(V, cCodeCheckEn_f, &ds, 1);
#if (SDK_WORK_PLATFORM == 0)
    SetFlexEOamParserCtl(V, crcCheckEn_f, &ds, 1);
#endif
    SetFlexEOamParserCtl(V, csTypeResCheckEn_f, &ds, 1);
    SetFlexEOamParserCtl(V, spnCodeTypeCheckEn_f, &ds, 1);
    SetFlexEOamParserCtl(V, oamTypeMask_f, &ds, 0x3F << 2);
    SetFlexEOamParserCtl(V, basInvalidReiCheckEn_f, &ds, 1);
    SetFlexEOamParserCtl(V, basInvalidRei_f, &ds, 0x9);
    cmd = DRV_IOW(FlexEOamParserCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamRxProcCtl(V, apsToCpuEn_f, &ds,  1);
    SetFlexEOamRxProcCtl(V, apsTriggerDmaEn_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, basLocCountCfg_f, &ds,  3);
    SetFlexEOamRxProcCtl(V, basPeriodCheckEn_f, &ds,  1);
    SetFlexEOamRxProcCtl(V, bipStoreNum_f, &ds,  3);
    SetFlexEOamRxProcCtl(V, dmDmaPriType_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, dmProcInCpu_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, csProcInCpu_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, cvProcInCpu_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, basProcInCpu_f, &ds,  0);
    SetFlexEOamRxProcCtl(V, unknownOamDefectEn_f, &ds,  1);
    SetFlexEOamRxProcCtl(V, csSeqChkEn_f, &ds,  1);
    SetFlexEOamRxProcCtl(A, defectReportDmaEn_f, &ds,  defect);
    SetFlexEOamRxProcCtl(A, defectReportDmaPriM_f, &ds,  defect);
    defect[0]=0;
    defect[1]=0;
    SetFlexEOamRxProcCtl(A, defectReportDmaPriL_f, &ds, defect);
    SetFlexEOamRxProcCtl(V, defectReportRdiEn_f, &ds,  0);

    cmd = DRV_IOW(FlexEOamRxProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamTxScanCtl(V, maxPtr_f, &ds, SYS_DEFECT_NUM);
    SetFlexEOamTxScanCtl(V, minPtr_f, &ds, 0);
    SetFlexEOamTxScanCtl(V, scanStopOnMaxPtr_f, &ds, 0);
    SetFlexEOamTxScanCtl(V, updEn_f, &ds, 1);
    cmd = DRV_IOW(FlexEOamTxScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamUpdateCtl(V, spnCodeType_f, &ds, SYS_SC_SPN_CODE);
    SetFlexEOamUpdateCtl(V, cCodeTxCfg_f, &ds, SYS_SC_SPN_C_CODE);
    SetFlexEOamUpdateCtl(V, basBlockType_f, &ds, SYS_SC_TYPE_BAS);
    SetFlexEOamUpdateCtl(V, apsBlockType_f, &ds, SYS_SC_TYPE_APS);
    SetFlexEOamUpdateCtl(V, cvBlockType_f, &ds, SYS_SC_TYPE_CV);
    SetFlexEOamUpdateCtl(V, _1dmBlockType_f, &ds, SYS_SC_TYPE_1DM);
    SetFlexEOamUpdateCtl(V, dmmBlockType_f, &ds, SYS_SC_TYPE_DMM);
    SetFlexEOamUpdateCtl(V, csBlockType_f, &ds, SYS_SC_TYPE_CS);
    value = 0;
    CTC_BIT_SET(value, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_BASLOC));
    CTC_BIT_SET(value, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_DLOCRXCLEAR));
    SetFlexEOamUpdateCtl(V, defectReportDmaEn_f, &ds, value);
    SetFlexEOamUpdateCtl(V, defectReportDmaPriM_f, &ds, value);
    SetFlexEOamUpdateCtl(V, defectReportDmaPriL_f, &ds, 0);
    SetFlexEOamUpdateCtl(V, dontCareFirstRx_f, &ds, 0);
    cmd = DRV_IOW(FlexEOamUpdateCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamPacketEditCtl(V, spnCodeType_f, &ds, SYS_SC_SPN_CODE);
    SetFlexEOamPacketEditCtl(V, cCodeTxCfg_f, &ds, SYS_SC_SPN_C_CODE);
    SetFlexEOamPacketEditCtl(V, dmrBlockType_f, &ds, SYS_SC_TYPE_DMR);
    cmd = DRV_IOW(FlexEOamPacketEditCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamParserOffsetCtl(V, oamTypeByteOffset_f, &ds, SYS_SC_BYTE_OFFSET1);
    SetFlexEOamParserOffsetCtl(V, cCodeByteOffset_f, &ds, SYS_SC_BYTE_OFFSET4);
    SetFlexEOamParserOffsetCtl(V, cCodeBitOffset_f, &ds, 0);
    SetFlexEOamParserOffsetCtl(V, seqByteOffset_f, &ds, SYS_SC_BYTE_OFFSET7);
    SetFlexEOamParserOffsetCtl(V, seqBitOffset_f, &ds, 0);
    SetFlexEOamParserOffsetCtl(V, crcByteOffset_f, &ds, SYS_SC_BYTE_OFFSET7);
    SetFlexEOamParserOffsetCtl(V, crcBitOffset_f, &ds, 4);
    /*BAS*/
    SetFlexEOamParserOffsetCtl(V, reiByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, reiBitOffset_f, &ds, 0);
    SetFlexEOamParserOffsetCtl(V, rdiByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, rdiBitOffset_f, &ds, 4);
    SetFlexEOamParserOffsetCtl(V, csLpiByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, csLpiBitOffset_f, &ds, 5);
    SetFlexEOamParserOffsetCtl(V, csLfByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, csLfBitOffset_f, &ds, 6);
    SetFlexEOamParserOffsetCtl(V, csRfByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, csRfBitOffset_f, &ds, 7);
    SetFlexEOamParserOffsetCtl(V, periodByteOffset_f, &ds, SYS_SC_BYTE_OFFSET3);
    SetFlexEOamParserOffsetCtl(V, periodBitOffset_f, &ds, 6);
    SetFlexEOamParserOffsetCtl(V, bipByteOffset_f, &ds, SYS_SC_BYTE_OFFSET6);
    /*APS*/
    SetFlexEOamParserOffsetCtl(V, apsStateByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, apsStateBitOffset_f, &ds, 4);
    SetFlexEOamParserOffsetCtl(V, apsTypeByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, apsTypeBitOffset_f, &ds, 0);
    SetFlexEOamParserOffsetCtl(V, apsReqSigByteOffset_f, &ds, SYS_SC_BYTE_OFFSET3);
    SetFlexEOamParserOffsetCtl(V, apsBridgeSigByteOffset_f, &ds, SYS_SC_BYTE_OFFSET5);
    /*CV*/
    SetFlexEOamParserOffsetCtl(V, sdapiByteOffset0_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, sdapiByteOffset1_f, &ds, SYS_SC_BYTE_OFFSET3);
    SetFlexEOamParserOffsetCtl(V, sdapiByteOffset2_f, &ds, SYS_SC_BYTE_OFFSET5);
    SetFlexEOamParserOffsetCtl(V, sdapiByteOffset3_f, &ds, SYS_SC_BYTE_OFFSET6);
    /*DM*/
    SetFlexEOamParserOffsetCtl(V, dmByteOffset0_f, &ds, SYS_SC_BYTE_OFFSET2);
    SetFlexEOamParserOffsetCtl(V, dmByteOffset1_f, &ds, SYS_SC_BYTE_OFFSET3);
    SetFlexEOamParserOffsetCtl(V, dmByteOffset2_f, &ds, SYS_SC_BYTE_OFFSET5);
    SetFlexEOamParserOffsetCtl(V, dmByteOffset3_f, &ds, SYS_SC_BYTE_OFFSET6);
    /*CV*/
    SetFlexEOamParserOffsetCtl(V, csTypeByteOffset_f, &ds, SYS_SC_BYTE_OFFSET2);
    cmd = DRV_IOW(FlexEOamParserOffsetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamHeaderAdjustScanCtl(V, scanEn_f, &ds, 1);
    cmd = DRV_IOW(FlexEOamHeaderAdjustScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    SetFlexEOamBasTxIntervalMap(V, array_0_basPeriod_f, &ds, 0);
    SetFlexEOamBasTxIntervalMap(V, array_1_basPeriod_f, &ds, 1);
    SetFlexEOamBasTxIntervalMap(V, array_3_basPeriod_f, &ds, 2);
    SetFlexEOamBasTxIntervalMap(V, array_31_basPeriod_f, &ds, 3);
    cmd = DRV_IOW(FlexEOamBasTxIntervalMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    sal_memset(&ds, 0 , sizeof(ds_t));
    CTC_BMP_SET(defect, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));/*APS RX must by DMA*/
    SetFlexEOamDmaCtl(V, criticalThresholdL_f, &ds, 64);
    SetFlexEOamDmaCtl(V, criticalThresholdM_f, &ds, 64);
    SetFlexEOamDmaCtl(A, critialDefectL_f, &ds, defect);
    SetFlexEOamDmaCtl(A, critialDefectM_f, &ds, defect);
    cmd = DRV_IOW(FlexEOamDmaCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    value = 0x400;
    SetRefDivSpnOamTxPulse(V, cfgRefDivSpnOamTxPulse_f, &ds, value);
    cmd = DRV_IOW(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOW(DsFlexEOamTxScanCfg_t, DRV_ENTRY_FLAG);
    for (index = 0; index < TABLE_MAX_INDEX(lchip, DsFlexEOamTxScanCfg_t); index++)
    {
        SetDsFlexEOamTxScanCfg(V, array_0_counterThrd_f, &ds, 0x3FFF);
        SetDsFlexEOamTxScanCfg(V, array_1_counterThrd_f, &ds, 0x3FFF);
        SetDsFlexEOamTxScanCfg(V, array_2_counterThrd_f, &ds, 0x3FFF);
        SetDsFlexEOamTxScanCfg(V, array_3_counterThrd_f, &ds, 0x3FFF);
        SetDsFlexEOamTxScanCfg(V, array_4_counterThrd_f, &ds, 0x3FFF);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    dma_map.type = SYS_DMA_REPORT_TYPE_SPNOAM_LOCAL;
    CTC_BIT_SET(dma_map.dest_bmp, SYS_DMA_EXP_DEST_TYPE_EUNIT);
    CTC_ERROR_RETURN(sys_usw_dma_export_map(lchip, &dma_map));

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_sc_oam_mep_check(uint8 lchip, ctc_sc_oam_mep_t* p_mep)
{
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (((p_mep->client_speed % 5) != 0) || (0 == p_mep->client_speed))
    {
        return  CTC_E_INVALID_PARAM;
    }

    if ((p_mep->rx_en_bmp&(~0x3D))
        || (p_mep->tx_en_bmp&(~0x3D)))/*APS can not config ebable when adding client*/
    {
        return  CTC_E_INVALID_PARAM;
    }

    /*BAS*/
    CTC_MAX_VALUE_CHECK(p_mep->bas_rx_period, CTC_SC_OAM_PERIOD_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_mep->bas_tx_period, CTC_SC_OAM_PERIOD_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_mep->bas_seq_mode, 1);
    CTC_MAX_VALUE_CHECK(p_mep->bas_seq, 0xF);
    CTC_MAX_VALUE_CHECK(p_mep->cs_lpi, 1);
    CTC_MAX_VALUE_CHECK(p_mep->cs_lf, 1);
    CTC_MAX_VALUE_CHECK(p_mep->cs_rf, 1);
    CTC_MAX_VALUE_CHECK(p_mep->rdi, 1);
    CTC_MAX_VALUE_CHECK(p_mep->ber_thrd.ber_detect_time, 0xFFFFFFF);
    CTC_MAX_VALUE_CHECK(p_mep->rei_thrd.ber_detect_time, 0xFFFFFFF);
    /*APS*/
    CTC_MAX_VALUE_CHECK(p_mep->aps_interval, 60);
    /*CV*/
    CTC_MAX_VALUE_CHECK(p_mep->cv_interval, 60);
    /*DM*/
    CTC_MAX_VALUE_CHECK(p_mep->one_dm_interval, 60);
    CTC_MAX_VALUE_CHECK(p_mep->two_dm_interval, 60);
    /*CS*/
    CTC_MAX_VALUE_CHECK(p_mep->cs_interval, 60);
    CTC_MAX_VALUE_CHECK(p_mep->cs_type, 0xF);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_mep_prop_check(uint8 lchip, ctc_sc_oam_mep_prop_t* p_mep_prop)
{
    uint8 use_aps = 0;
    uint8 bridge_permanent = 0;
    uint8 direction = 0;
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    switch (p_mep_prop->prop_type)
    {
        case CTC_SC_OAM_MEP_PROP_CLIENT_SPEED:
            if (((p_mep_prop->update_value % 5) != 0) || (0 == p_mep_prop->update_value)
                || (p_mep_prop->update_value > 0xFFFF))
            {
                return  CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_RX_EN_BMP:
        case CTC_SC_OAM_MEP_PROP_TX_EN_BMP:
            if (p_mep_prop->update_value&(~0x3F))
            {
                return  CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_RX_PERIOD:
        case CTC_SC_OAM_MEP_PROP_BAS_TX_PERIOD:
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, CTC_SC_OAM_PERIOD_MAX - 1);
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ_MODE:
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, 1);
            break;
        case CTC_SC_OAM_MEP_PROP_BAS_SEQ:
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, 0xF);
            break;
        case CTC_SC_OAM_MEP_PROP_BER_THRD:
        case CTC_SC_OAM_MEP_PROP_REI_THRD:
        {
            sys_sc_oam_mep_t* p_mep_db = NULL;
            ctc_sc_oam_ber_thrd_t* ber_thrd = (ctc_sc_oam_ber_thrd_t*)p_mep_prop->p_update_value;
            CTC_MAX_VALUE_CHECK(ber_thrd->ber_detect_time, 0xFFFFFFF);
            p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep_prop->client_id);
            if (p_mep_db)
            {
                uint8 period=0;
                period = _sys_usw_sc_oam_map_bas_period(lchip, p_mep_db->bas_tx_period, 0) + 1;
                CTC_MAX_VALUE_CHECK(SYS_SC_OAM_BER(ber_thrd->ber_detect_time, period, ber_thrd->ddeg_set_thrd), CTC_MAX_UINT32_VALUE);
                CTC_MAX_VALUE_CHECK(SYS_SC_OAM_BER(ber_thrd->ber_detect_time, period, ber_thrd->ddeg_clear_thrd), CTC_MAX_UINT32_VALUE);
                CTC_MAX_VALUE_CHECK(SYS_SC_OAM_BER(ber_thrd->ber_detect_time, period, ber_thrd->dexc_set_thrd), CTC_MAX_UINT32_VALUE);
                CTC_MAX_VALUE_CHECK(SYS_SC_OAM_BER(ber_thrd->ber_detect_time, period, ber_thrd->dexc_clear_thrd), CTC_MAX_UINT32_VALUE);
            }
        }
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INTERVAL:
        case CTC_SC_OAM_MEP_PROP_CV_INTERVAL:
        case CTC_SC_OAM_MEP_PROP_1DM_INTERVAL:
        case CTC_SC_OAM_MEP_PROP_2DM_INTERVAL:
        case CTC_SC_OAM_MEP_PROP_CS_INTERVAL:
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, 60);
            break;
        case CTC_SC_OAM_MEP_PROP_APS_TX_RAPID:
            if (g_sc_oam_master[lchip]->hw_aps)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need disable HW APS!\n");
                return CTC_E_INVALID_CONFIG;
            }
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, 3);
            break;
        case CTC_SC_OAM_MEP_PROP_APS_INFO:
        {
            ctc_sc_oam_aps_info_t* aps_info = (ctc_sc_oam_aps_info_t*)p_mep_prop->p_update_value;
            CTC_MAX_VALUE_CHECK(aps_info->request_state, 0xF);
            CTC_MAX_VALUE_CHECK(aps_info->protection_type, 0xF);
            bridge_permanent = !CTC_IS_BIT_SET(aps_info->protection_type, 2);
            use_aps = CTC_IS_BIT_SET(aps_info->protection_type, 3);
            direction = CTC_IS_BIT_SET(aps_info->protection_type, 1);

            if (!use_aps && !aps_info->is_protection)
            {
                if (!(bridge_permanent && (!direction)))
                {
                    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "1:1 or bidirectional need a APS communication!\n");
                    return CTC_E_INVALID_PARAM;
                }
            }
            if ((0 == g_sc_oam_master[lchip]->hw_aps) && aps_info->aps_en)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need enable HW APS!\n");
                return CTC_E_INVALID_CONFIG;
            }
        }
            break;
        case CTC_SC_OAM_MEP_PROP_APS_CMD:
            if (0 == g_sc_oam_master[lchip]->hw_aps)
            {
                SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Need enable HW APS!\n");
                return CTC_E_INVALID_CONFIG;
            }
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, CTC_SC_OAM_APS_CMD_MAX - 1);
            break;
        case CTC_SC_OAM_MEP_PROP_CS_TYPE:
            CTC_MAX_VALUE_CHECK(p_mep_prop->update_value, 0xF);
            break;
        default:
            break;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_unmap_defect(uint8 lchip, uint8 report_type, uint32 defect_vector[2], uint32* defect_bmp)
{
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "defect_vector[0] = 0x%x, defect_vector[1] = 0x%x\n", defect_vector[0], defect_vector[1]);
    /*1.  report in update timer*/
    if (SYS_DEFECT_TYPE_UPDATE == report_type)
    {
        if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_BASLOC))
            || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_DLOCRXCLEAR)))
        {
            CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DLOC);
        }
        return CTC_E_NONE;
    }

    /*2.  rx process*/
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSLPI))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLPI)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_CSLPI);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSLF))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLF)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_CSLF);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSRF))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSRF)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_CSRF);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETRDI))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARRDI)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_RDI);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDEXC))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDEXC)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DEXC);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDDEG))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDDEG)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DDEG);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDREIEXC))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIEXC)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DEXC_REI);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDREIDEG))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIDEG)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DDEG_REI);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DLOCRXCLEAR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DLOC);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_FIRSTRXBLOCK)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_FIRST_RX);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SEQCHECKFAIL))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CVSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE__1DMSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMMSEQMISMATCHCLEAR))
        ||CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMRSEQMISMATCHCLEAR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_SEQ_CHK);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SAPICHECKFAIL))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SAPICHECKCLEAR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_SAPI_CHK);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DAPICHECKFAIL))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DAPICHECKCLEAR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_DAPI_CHK);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSTYPEFAIL))
        || CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSTYPEFAILCLEAR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_CS_TYPE_CHK);
    }
    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASPERIODCHKFAIL))
        ||(CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASPERIODCHKCLEAR))))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_PERIOD_CHK);
    }

    if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CRCERROR)))
    {
        CTC_SET_FLAG(*defect_bmp, CTC_SC_OAM_DEFECT_CRC_CHK);
    }
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "defect_bmp = 0x%x\n", *defect_bmp);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_map_defect(uint8 lchip, uint8 report_type, uint32 defect_bmp, uint32 defect_vector[2], uint8 is_to_rdi)
{
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /*1.  report in update timer*/
    if (SYS_DEFECT_TYPE_UPDATE == report_type)
    {
        if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DLOC))
        {
            CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_BASLOC));
            if (0 == is_to_rdi)
            {
                CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMUPDATEDEFECTTYPE_DLOCRXCLEAR));
            }
        }
        return CTC_E_NONE;
    }

    /*2.  rx process*/
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_CSLPI))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSLPI));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLPI));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_CSLF))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSLF));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLF));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_CSRF))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETCSRF));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSRF));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_RDI))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETRDI));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARRDI));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DEXC))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDEXC));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDEXC));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DDEG))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDDEG));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDDEG));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DEXC_REI))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDREIEXC));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIEXC));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DDEG_REI))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETDREIDEG));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIDEG));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DLOC))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DLOCRXCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_FIRST_RX))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_FIRSTRXBLOCK));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_SEQ_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SEQCHECKFAIL));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CVSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE__1DMSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMMSEQMISMATCHCLEAR));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMRSEQMISMATCHCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_SAPI_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SAPICHECKFAIL));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SAPICHECKCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_DAPI_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DAPICHECKFAIL));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DAPICHECKCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_CS_TYPE_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSTYPEFAIL));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSTYPEFAILCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_PERIOD_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASPERIODCHKFAIL));
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASPERIODCHKCLEAR));
    }
    if (CTC_FLAG_ISSET(defect_bmp, CTC_SC_OAM_DEFECT_CRC_CHK))
    {
        CTC_BMP_SET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CRCERROR));
    }

    if (is_to_rdi)/*clear status not triger rdi*/
    {
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLPI));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSLF));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARCSRF));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDEXC));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDDEG));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DAPICHECKCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSTYPEFAILCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIEXC));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CLEARDREIDEG));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASPERIODCHKCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_BASSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CVSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CSSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE__1DMSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMMSEQMISMATCHCLEAR));
        CTC_BMP_UNSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_DMRSEQMISMATCHCLEAR));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_sc_oam_db_free_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);
    return CTC_E_NONE;
}

int32
_sys_usw_sc_oam_wb_mapping(uint8 lchip, uint32 client_id, sys_sc_oam_mep_t* p_mep_db)
{
    ds_t ds;
    uint32 cmd = 0;
    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEMepCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, client_id, cmd, &ds));
    p_mep_db->rei_id = GetDsFlexEMepCfg(V, reiProfileId_f, &ds);
    p_mep_db->ber_id = GetDsFlexEMepCfg(V, berProfileId_f, &ds);


    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEOamReiProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->rei_id, cmd, &ds));

    p_mep_db->rei_thrd.dexc_clear_thrd = GetDsFlexEOamBerProfile(V, dExcDetectClearThreshold_f, &ds);
    p_mep_db->rei_thrd.dexc_set_thrd = GetDsFlexEOamBerProfile(V, dExcDetectThreshold_f, &ds);
    p_mep_db->rei_thrd.ddeg_clear_thrd = GetDsFlexEOamBerProfile(V, dDegDetectClearThreshold_f, &ds);
    p_mep_db->rei_thrd.ddeg_set_thrd = GetDsFlexEOamBerProfile(V, dDegDetectThreshold_f, &ds);
    p_mep_db->rei_thrd.ber_detect_time = GetDsFlexEOamBerProfile(V, testPeriod_f, &ds);

    sal_memset(&ds, 0 , sizeof(ds_t));
    cmd = DRV_IOR(DsFlexEOamBerProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_mep_db->ber_id, cmd, &ds));

    p_mep_db->ber_thrd.dexc_clear_thrd = GetDsFlexEOamBerProfile(V, dExcDetectClearThreshold_f, &ds);
    p_mep_db->ber_thrd.dexc_set_thrd = GetDsFlexEOamBerProfile(V, dExcDetectThreshold_f, &ds);
    p_mep_db->ber_thrd.ddeg_clear_thrd = GetDsFlexEOamBerProfile(V, dDegDetectClearThreshold_f, &ds);
    p_mep_db->ber_thrd.ddeg_set_thrd = GetDsFlexEOamBerProfile(V, dDegDetectThreshold_f, &ds);
    p_mep_db->ber_thrd.ber_detect_time = GetDsFlexEOamBerProfile(V, testPeriod_f, &ds);
    return CTC_E_NONE;
}

int32
_sys_usw_sc_oam_wb_traverse_sync_node(void *data, void *user_data)
{
    int32 ret = 0;
    sys_sc_oam_mep_t* p_mep_db = (sys_sc_oam_mep_t*)data;
    sys_wb_sc_oam_mep_t * p_wb_sc_oam_mep_node = NULL;
    sys_traverse_t *wb_traverse = (sys_traverse_t*)user_data;
    ctc_wb_data_t *wb_data = wb_traverse->data;
    uint32 max_buffer_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);
    p_wb_sc_oam_mep_node = (sys_wb_sc_oam_mep_t *)wb_data->buffer + wb_data->valid_cnt;
    sal_memset(p_wb_sc_oam_mep_node, 0, sizeof(sys_wb_sc_oam_mep_t));
    p_wb_sc_oam_mep_node->client_id = p_mep_db->client_id;
    p_wb_sc_oam_mep_node->hw_client_id = p_mep_db->hw_client_id;
    p_wb_sc_oam_mep_node->client_speed = p_mep_db->client_speed;
    p_wb_sc_oam_mep_node->bas_tx_period = p_mep_db->bas_tx_period;
    p_wb_sc_oam_mep_node->rei_index = p_mep_db->rei_id;
    p_wb_sc_oam_mep_node->ber_index = p_mep_db->ber_id;
    p_wb_sc_oam_mep_node->aps_grp_id = p_mep_db->aps_grp_id;
    if (++wb_data->valid_cnt ==  max_buffer_cnt)
    {
        ret = ctc_wb_add_entry(wb_data);
        if ( ret != CTC_E_NONE )
        {
            return ret;
        }
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}
STATIC int32
_sys_usw_sc_oam_get_defect_bmp(uint8 lchip, sys_sc_oam_mep_t* p_mep_db,uint32* defect_bmp)
{
    ctc_sc_oam_mep_info_t mep_info;
    uint32 defect_bmp_tmp=0;

    sal_memset(&mep_info,0,sizeof(ctc_sc_oam_mep_info_t));
    CTC_ERROR_RETURN(_sys_usw_sc_oam_dump_state(lchip, p_mep_db, &mep_info));

    if (mep_info.first_rx)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_FIRST_RX);
    }
    if (mep_info.dloc)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DLOC);
    }
    if (mep_info.seq_chk)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_SEQ_CHK);
    }
    if (mep_info.sapi_chk)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_SAPI_CHK);
    }
    if (mep_info.dapi_chk)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DAPI_CHK);
    }
    if (mep_info.cs_type_chk)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_CS_TYPE_CHK);
    }
    if (mep_info.remote_period_chk)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_PERIOD_CHK);
    }
    if (mep_info.ddeg)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DDEG);
    }
    if (mep_info.dexc)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DEXC);
    }
    if (mep_info.ddeg_rei)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DDEG_REI);
    }
    if (mep_info.dexc_rei)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_DEXC_REI);
    }
    if (mep_info.remote_cs_lpi)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_CSLPI);
    }
    if (mep_info.remote_cs_lf)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_CSLF);
    }
    if (mep_info.remote_cs_rf)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_CSRF);
    }
    if (mep_info.remote_rdi)
    {
        CTC_SET_FLAG(defect_bmp_tmp, CTC_SC_OAM_DEFECT_RDI);
    }
    *defect_bmp = defect_bmp_tmp;
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "defect_bmp = 0x%x\n", *defect_bmp);
    return CTC_E_NONE;
}

int32
_sys_usw_sc_oam_dump_db_traverse(void *data, void *user_data)
{
    sal_file_t p_f = NULL;
    sys_sc_oam_mep_t* p_mep_db = (sys_sc_oam_mep_t*)data;
    sys_traverse_t *dump_db_traverse = (sys_traverse_t*)user_data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = dump_db_traverse->value1;
#endif
    p_f = dump_db_traverse->data;
    SYS_DUMP_DB_LOG(p_f, "%-12u%-15u%-15u%-15u\n", p_mep_db->client_id, p_mep_db->client_speed, p_mep_db->bas_tx_period, p_mep_db->aps_grp_id);
    return CTC_E_NONE;
}


#define _________API_________

int32
sys_usw_sc_oam_set_period( uint8 lchip, uint16 client_speed, uint32 client_id)
{
    int32 ret=0;
    uint16 hw_client_id=0;
    SE_OAM_LOCK(lchip);

    CTC_ERROR_GOTO(sys_usw_flexe_get_client_property(lchip, client_id,
                                                                 SYS_FLEXE_CLIENT_PROP_HW_CLIENT, &hw_client_id), ret, end);
    ret = _sys_usw_sc_oam_set_period(lchip, hw_client_id, client_speed);
    end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_flexe_tx( uint8 lchip, uint32 packet_len, uint8 chan_id,uint8 instance_id,uint8 dp_id,uint8 blockdata[])
{
    uint32 cmd = 0;
    uint32 value = 0;
    FlexeMgrCpuTxLoadData_m cpu_tx_load;
    FlexeMgrCfg_m mgr_cfg;
    uint32 CpuTxData[4] ={0};
    uint8 i=0;
    uint32* p_hdr = NULL;
    uint8 pkt_index =0;
    uint8 index =0;
    uint8 remnant =0;
    uint8 max_array =0;
    sal_memset(&cpu_tx_load, 0, sizeof(FlexeMgrCpuTxLoadData_m));
    if (chan_id > 2)
    {
        return CTC_E_INVALID_PARAM;
    }
    value =1;
    cmd = DRV_IOR(FlexeMgrCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &mgr_cfg));
    SetFlexeMgrCfg(V, cfgTxPktMode_f, &mgr_cfg, value);
    cmd = DRV_IOW(FlexeMgrCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &mgr_cfg));

    /*first 3 blocks PacketHeader*/
    cmd = DRV_IOW(FlexeMgrCpuTxLoadData_t, DRV_ENTRY_FLAG);
    CpuTxData[3]=((chan_id&0x3)<<2)+((instance_id&0x7)<<4);/*xxx(instance id)xx(chan id)00*/
    SetFlexeMgrCpuTxLoadData(V, cfgCpuTxSop_f, &cpu_tx_load, 1);
    SetFlexeMgrCpuTxLoadData(A, cfgCpuTxData_f, &cpu_tx_load,CpuTxData);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_tx_load));

    sal_memset(&cpu_tx_load, 0, sizeof(FlexeMgrCpuTxLoadData_m));
    SetFlexeMgrCpuTxLoadData(V, cfgCpuTxSop_f, &cpu_tx_load, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_tx_load));
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_tx_load));

    /*ptp message*/
    p_hdr  = (uint32*)blockdata;
    for (i=0;i<packet_len/16;i++)
    {
        for (pkt_index = 0; pkt_index < 4; pkt_index++)
        {
            value = DRV_SWAP32(p_hdr[i*4 + pkt_index]);
            CpuTxData[3 - pkt_index] = value;
        }
        SetFlexeMgrCpuTxLoadData(V, cfgCpuTxSop_f, &cpu_tx_load, 0);
        SetFlexeMgrCpuTxLoadData(A, cfgCpuTxData_f, &cpu_tx_load, CpuTxData);
        if (!(packet_len % 16) && (i == ((packet_len / 16) - 1)))
        {
            SetFlexeMgrCpuTxLoadData(V, cfgCpuTxEopBytes_f, &cpu_tx_load, 16);
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_tx_load));
    }
    sal_memset(&cpu_tx_load, 0, sizeof(FlexeMgrCpuTxLoadData_m));
    sal_memset(CpuTxData, 0, sizeof(CpuTxData));

    remnant = packet_len%16;
    if (remnant)
    {
       index = packet_len/16;
        if (remnant% 4)
        {
            max_array = remnant / 4 + 1;
        }
        else
        {
            max_array = remnant /4 ;
        }
         for (pkt_index = 0; pkt_index < max_array; pkt_index++)
         {
             value = DRV_SWAP32(p_hdr[index*4 + pkt_index]);
             CpuTxData[3 - pkt_index] = value;
         }
         SetFlexeMgrCpuTxLoadData(A, cfgCpuTxData_f, &cpu_tx_load, CpuTxData);
         SetFlexeMgrCpuTxLoadData(V, cfgCpuTxEopBytes_f, &cpu_tx_load, packet_len % 16);
     }
    SetFlexeMgrCpuTxLoadData(V, cfgCpuTxEop_f, &cpu_tx_load, 1);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_tx_load));
    return CTC_E_NONE;

}


int32
sys_usw_flexe_rx( uint8 lchip, uint32 *packet_len, uint8 blockdata[], uint8 dp_id)
{
    uint32 cmd = 0;
    uint32 value = 0;
    FlexeMgrCpuRxDumpData_m cpu_rx_dump;
    FlexeMgrCfg_m mgr_cfg;
    uint32 CpuRxData[4] ={0};
    uint8 i = 0;
    uint32 j=0;
    uint8 loop =0;
    uint8 is_eop=0;
    uint8 is_sop=0;
    uint8 rx_valid=0;
    uint8 eop_bytes=0;
    sal_memset(&cpu_rx_dump, 0, sizeof(FlexeMgrCpuRxDumpData_m));
    value =1;
    cmd = DRV_IOR(FlexeMgrCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &mgr_cfg));
    SetFlexeMgrCfg(V, cfgRxPktMode_f, &mgr_cfg, value);
    cmd = DRV_IOW(FlexeMgrCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &mgr_cfg));

    cmd = DRV_IOR(FlexeMgrCpuRxDumpData_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_rx_dump));
    rx_valid = GetFlexeMgrCpuRxDumpData(V,monCpuRxValid_f,&cpu_rx_dump);
    is_sop =  GetFlexeMgrCpuRxDumpData(V,monCpuRxSop_f,&cpu_rx_dump);
    if (is_sop && rx_valid)
    {
     SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "*********Begin to read************\n");
        for (j=0;j<10000 ;j++ )
        {
            rx_valid = GetFlexeMgrCpuRxDumpData(V, monCpuRxValid_f, &cpu_rx_dump);
            is_eop =  GetFlexeMgrCpuRxDumpData(V, monCpuRxEop_f, &cpu_rx_dump);
            if (GetFlexeMgrCpuRxDumpData(V, monCpuRxError_f, &cpu_rx_dump))
            {
                return CTC_E_INVALID_PARAM;
            }

            if (rx_valid)
            {
                GetFlexeMgrCpuRxDumpData(A, monCpuRxData_f, &cpu_rx_dump, CpuRxData);
                if (loop >=3)
                {
                    for (i = 0; i < 16; i++)
                    {
                        blockdata[i + 16*(loop-3)] = (CpuRxData[3 - i / 4] >> (8*(3 - i % 4)))&0xFF;
                    }
                }
                if (is_eop)
                {
                    eop_bytes = GetFlexeMgrCpuRxDumpData(V, monCpuRxEopBytes_f, &cpu_rx_dump);
                    *packet_len = loop*16 + eop_bytes-48;
                    return CTC_E_NONE;
                }
                loop++;
            }
            sal_task_sleep(1);
            cmd = DRV_IOR(FlexeMgrCpuRxDumpData_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &cpu_rx_dump));
        }
         return CTC_E_HW_BUSY;
    }
    return CTC_E_NONE;
    }

int32
sys_usw_sc_oam_cpu_tx_by_acc(uint32 client_id,uint8 block_num, uint8 seqnum,uint8 highpri,uint8* blockdata)
{
    uint32 cmd = 0;
    uint32 loop = 0;
    uint32 count = 0;
    uint32 cpuReqDone = 0;
    uint8 OamBlockData[8] ={0};
    uint8 data=0;
    uint8 lchip=0;
    uint8 i=0;
    uint32 step=0;
    FlexEOamPacketTxCpuReq_m cpuReq;
    sal_memset(&cpuReq, 0, sizeof(cpuReq));
    if (block_num >= SYS_SC_CPU_TX_MAX_BLOCK_NUM)
    {
        return CTC_E_INVALID_PARAM;
    }

    /* clear result*/
    cmd = DRV_IOW(FlexEOamPacketTxCpuResult_t, FlexEOamPacketTxCpuResult_txPacketDone_f);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpuReqDone))

    for(i=0;i<block_num;i++)
    {
        sal_memcpy(OamBlockData, blockdata+8*i, 8);
        data = OamBlockData[1];/*type*/
        OamBlockData[1] = data << 2;
        data = OamBlockData[4];/*ccode*/
        OamBlockData[4] = ((data >> 4)&0xF) + ((data&0xF) << 4);
        data = OamBlockData[7];/*seq|crc*/
        OamBlockData[7] = ((data >> 4)&0xF) + ((data&0xF) << 4);

        if (OamBlockData[1] == 0x1)/*BAS*/
        {
            data = OamBlockData[2];/*data2*/
            for (loop = 0; loop < 8; loop++)
            {
                if (CTC_IS_BIT_SET(data, loop))
                {
                    CTC_BIT_SET(OamBlockData[2], (8 - loop - 1));
                }
                else
                {
                    CTC_BIT_UNSET(OamBlockData[2], (8 - loop - 1));
                }
            }

            data = OamBlockData[3];/*period*/
            OamBlockData[3] = ((data&0x1) << 7) + ((data&0x2) << 6);
        }
        step = FlexEOamPacketTxCpuReq_array_1_captureTsEn_f - FlexEOamPacketTxCpuReq_array_0_captureTsEn_f;
        SetFlexEOamPacketTxCpuReq(V, array_0_captureTsEn_f+step*i, &cpuReq, 1);
        SetFlexEOamPacketTxCpuReq(V, array_0_txDmLsbEn_f+step*i, &cpuReq, 1);
        SetFlexEOamPacketTxCpuReq(V, array_0_clientId_f+step*i, &cpuReq, client_id);
        SetFlexEOamPacketTxCpuReq(V, array_0_seq_f+step*i, &cpuReq, OamBlockData[7]&0xF);
        SetFlexEOamPacketTxCpuReq(V, array_0_highPri_f+step*i, &cpuReq, highpri);
        SetFlexEOamPacketTxCpuReq(A, array_0_oamBlockData_f+step*i, &cpuReq, OamBlockData);

    }
    SetFlexEOamPacketTxCpuReq(V, packetTxReqValid_f, &cpuReq, 1);
    SetFlexEOamPacketTxCpuReq(V, txBlockNum_f, &cpuReq,block_num);
    cmd = DRV_IOW(FlexEOamPacketTxCpuReq_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpuReq));
     /*2. wait result done*/
     cmd = DRV_IOR(FlexEOamPacketTxCpuResult_t, FlexEOamPacketTxCpuResult_txPacketDone_f);
    for (loop = 0; (loop < 2000) && !cpuReqDone; loop++)
    {
        for (count = 0; (count < 150) && !cpuReqDone; count++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpuReqDone));
        }

        if (cpuReqDone)
        {
            return CTC_E_NONE;
        }
        sal_task_sleep(1);
    }
    return CTC_E_HW_BUSY;
}


int32
sys_usw_sc_oam_event_cb(uint8 gchip, void* data)
{
    ctc_sc_oam_event_t* event = data;
    uint32 client_num=0;
    uint32 i = 0;
    uint8 lchip = 0;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    uint32 mep_defect_bitmap_cmp    = 0;
    char* desc[32] =
    {
        "CTC_SC_OAM_DEFECT_CSLPI",
        "CTC_SC_OAM_DEFECT_CSLF",
        "CTC_SC_OAM_DEFECT_CSRF",
        "CTC_SC_OAM_DEFECT_RDI",
        "CTC_SC_OAM_DEFECT_DEXC",
        "CTC_SC_OAM_DEFECT_DDEG",
        "CTC_SC_OAM_DEFECT_DEXC_REI",
        "CTC_SC_OAM_DEFECT_DDEG_REI",
        "CTC_SC_OAM_DEFECT_DLOC",
        "CTC_SC_OAM_DEFECT_FIRST_RX",
        "CTC_SC_OAM_DEFECT_SEQ_CHK",
        "CTC_SC_OAM_DEFECT_SAPI_CHK",
        "CTC_SC_OAM_DEFECT_DAPI_CHK",
        "CTC_SC_OAM_DEFECT_CS_TYPE_CHK",
        "CTC_SC_OAM_DEFECT_PERIOD_CHK",
        "CTC_SC_OAM_DEFECT_CRC_CHK",
        "CTC_SC_OAM_DEFECT_APS_MISMATCH",
        "CTC_SC_OAM_DEFECT_APS_STATE_CHANGE",
        "CTC_SC_OAM_DEFECT_APS_PATH_SWITCH"
    };
    CTC_ERROR_RETURN(sys_usw_get_local_chip_id(gchip, &lchip));
    CTC_PTR_VALID_CHECK(data);
    for(client_num=0;client_num<event->valid_num;client_num++)
    {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n----------------------------Event Occur %d--------------------------\n", client_num);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Client     :%u\n", event->event_entry[client_num].client_id);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Defect BMP :0x%08x\n", event->event_entry[client_num].defect_bmp);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Event Type :0x%08x\n", event->event_entry[client_num].event_type);

        p_mep_db = _sys_usw_sc_oam_lkup(lchip, event->event_entry[client_num].client_id);
        if (NULL == p_mep_db)
        {
            continue;
        }
        mep_defect_bitmap_cmp = event->event_entry[client_num].defect_bmp ^ g_sc_oam_master[lchip]->mep_defect_bitmap[p_mep_db->hw_client_id];
        for (i = 0; i < 32; i++)
        {
            if ((1 << i) > CTC_SC_OAM_DEFECT_PERIOD_CHK)
            {
                if (CTC_IS_BIT_SET(event->event_entry[client_num].defect_bmp, i))
                {
                    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Defect     :%s\n", desc[i]);
                }
            }
            else
            {
                if (CTC_IS_BIT_SET(mep_defect_bitmap_cmp, i))
                {
                    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Defect     :%s\n", desc[i]);
                }
            }
        }

        if (event->event_entry[client_num].data_valid)
        {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "OAM Data   :%02X%02X%02X%02X%02X%02X%02X%02X\n",
                           event->event_entry[client_num].oam_data[0], event->event_entry[client_num].oam_data[1], event->event_entry[client_num].oam_data[2], event->event_entry[client_num].oam_data[3],
                           event->event_entry[client_num].oam_data[4], event->event_entry[client_num].oam_data[5], event->event_entry[client_num].oam_data[6], event->event_entry[client_num].oam_data[7]);
        }

        if (event->event_entry[client_num].event_type == CTC_SC_OAM_EVENT_TYPE_DM_RX)
        {
            SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s  :%us, %uns\n", event->event_entry[client_num].dm_event.dm_type? "DMR Delay" : "1DM Delay",
                               event->event_entry[client_num].dm_event.dm_delay.seconds, event->event_entry[client_num].dm_event.dm_delay.nanoseconds);
        }
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
        g_sc_oam_master[lchip]->mep_defect_bitmap[p_mep_db->hw_client_id] = event->event_entry[client_num].defect_bmp;
    }

    return CTC_E_NONE;
}

int32
sys_usw_sc_oam_sync_data(uint8 lchip, void* p_dma_info)
{
    sys_dma_info_t* p_info = (sys_dma_info_t*)p_dma_info;
    uint16 entry_num = 0;
    uint16 index = 0;
    CTC_INTERRUPT_EVENT_FUNC se_oam_cb = NULL;
    static ctc_sc_oam_event_t event;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    uint32 client_id = 0;
    uint32 defect_vector[2] = {0};
    uint8 oam_data[8] = {1,2,3,4,5,6,7,8};
    uint8 gchip = 0;
    uint8 report_type = 0;
    uint8 event_type = 0;
    uint8 tmp = 0;
    uint32 cmd =0;
    DsFlexEMep_m mep;
    DsFlexEMep_m mep_mask;
    int32 ret=0;
    DsFlexEApsCfg_m aps_cfg;
    CpuInfoFlexEOam_m* p_temp_fifo = NULL;
    ds_t data;
    SYS_SC_OAM_INIT_CHECK(lchip);
    sal_memset(&mep, 0 , sizeof(mep));
    sal_memset(&mep_mask, 0xFF , sizeof(mep_mask));
    sal_memset(&aps_cfg,0,sizeof(aps_cfg));
    sal_memset(&event, 0, sizeof(ctc_sc_oam_event_t));
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_SC_OAM, &se_oam_cb));
    if (!se_oam_cb)
    {
        return CTC_E_NOT_INIT;
    }
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));

    entry_num = p_info->entry_num;
    for (index = 0; index < entry_num; index++)
    {
        p_temp_fifo = (CpuInfoFlexEOam_m*)((uint8*)p_info->p_data + index * TABLE_ENTRY_SIZE(lchip, CpuInfoFlexEOam_t));
        GetCpuInfoFlexEOam(A, flexEOamDmaInfo_f, p_temp_fifo, &data);

        client_id = GetFlexEOamDmaInfo(V, clientId_f, &data);
        report_type = GetFlexEOamDmaInfo(V, dmaReportType_f, &data);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "client_id       = %d\n",   client_id);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "report_type     = %d\n",   report_type);

        SE_OAM_LOCK(lchip);
        p_mep_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip, client_id);
        if (NULL == p_mep_db)
        {
            SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not find SC Mep!!!\n");
            SE_OAM_UNLOCK(lchip);
            return CTC_E_NONE;
        }

        event.event_entry[event.valid_num]. client_id = p_mep_db->client_id;
        if (0 == report_type)/*dm event*/
        {
            /* 1dm & DMR delay event */
            uint32 ts_hw[2] = {0};
            uint64 nanoseconds = 0;
            event.event_entry[event.valid_num].dm_event.dm_type = GetFlexEOamDmaInfo(V, dmaDmType_f, &data) - 1;
            GetFlexEOamDmaInfo(A, dmaDmDelay_f, &data, ts_hw);
            nanoseconds = ((uint64)ts_hw[1] << 32) + ts_hw[0];
            event.event_entry[event.valid_num].dm_event.dm_delay.seconds = nanoseconds / MCHIP_CAP(SYS_CAP_PTP_NS_OR_NNS_VALUE);
            event.event_entry[event.valid_num].dm_event.dm_delay.nanoseconds = nanoseconds % MCHIP_CAP(SYS_CAP_PTP_NS_OR_NNS_VALUE);
            event_type = CTC_SC_OAM_EVENT_TYPE_DM_RX;
        }
        else/* report_type is 1 or 2, defect event*/
        {
            event_type = CTC_SC_OAM_EVENT_TYPE_DEFECT;
            GetFlexEOamDmaInfo(A, defectTypeVector_f, &data, defect_vector);
            SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "defect_vector[0]   = 0x%x, defect_vector[1]   = 0x%x\n",   defect_vector[0], defect_vector[1]);
            _sys_usw_sc_oam_get_defect_bmp(lchip, p_mep_db, &(event.event_entry[event.valid_num].defect_bmp));
            if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_SETRDI)))
            {
                CTC_SET_FLAG((event.event_entry[event.valid_num].defect_bmp), CTC_SC_OAM_DEFECT_RDI);
            }
            if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX)))
            {
                event_type = CTC_SC_OAM_EVENT_TYPE_APS_RX;
            }
            if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU)))
            {
                event_type = CTC_SC_OAM_EVENT_TYPE_OTHER_PDU;
            }
            if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU)))
            {
                event_type = CTC_SC_OAM_EVENT_TYPE_INVALID_PDU;
            }
            if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_CRCERROR)))
            {
                CTC_SET_FLAG((event.event_entry[event.valid_num].defect_bmp), CTC_SC_OAM_DEFECT_CRC_CHK);
            }
            if (CTC_FLAG_ISSET(event.event_entry[event.valid_num].defect_bmp, CTC_SC_OAM_DEFECT_CS_TYPE_CHK))/*When received a cs type check fail packet,will reply a cs type packet in 1 second */
            {
                cmd = DRV_IOR(DsFlexEMep_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, client_id, cmd, &mep),ret,error_proc);
                if (GetDsFlexEMep(V, dCsTypeMismatch_f, &mep))
                {
                    SetDsFlexEMep(V, csTxWhile_f, &mep,0);
                    SetDsFlexEMep(V, csTxWhile_f, &mep_mask, 0);
                    CTC_ERROR_GOTO(_sys_usw_sc_oam_write_by_acc(lchip, client_id, &mep, &mep_mask),ret,error_proc);
                }
            }
           if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX)))
           {
               uint32 value = 0;
               cmd = DRV_IOW(DsFlexEApsCfg_t, DsFlexEApsCfg_apsRxSuppress_f);
               CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, client_id, cmd, &aps_cfg), ret, error_proc);

               cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_ignoreApsRxCpuCtl_f);
               CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, error_proc);
           }
        }
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "final defect_bmp = 0x%x\n", event.event_entry[event.valid_num].defect_bmp);
        event.event_entry[event.valid_num].event_type = event_type;
        if (!(event.event_entry[event.valid_num].defect_bmp == CTC_SC_OAM_DEFECT_DLOC) || (event_type != CTC_SC_OAM_EVENT_TYPE_DEFECT))
        {
            /* CTC_SC_OAM_DEFECT_DLOC  have no OAM data */
            event.event_entry[event.valid_num].data_valid = 1;
            GetFlexEOamDmaInfo(A, oamBlock_f, &data, oam_data);
            /*convert format*/
            tmp = oam_data[1];/*oam type*/
            oam_data[1] = ((tmp >> 2)&0x3F) + ((tmp&0x3) << 6);
            tmp = oam_data[4];/*C code*/
            oam_data[4] = ((tmp >> 4)&0xF) + ((tmp&0xf) << 4);
            tmp = oam_data[7];/*seq|crc*/
            oam_data[7] = ((tmp >> 4)&0xF) + ((tmp&0xf) << 4);
            if ((oam_data[1]&0x3F) == 0x1)/*BAS*/
            {
                uint8 i = 0;
                tmp = oam_data[2];/*data2*/
                for (i = 0; i < 8; i++)
                {
                    if (CTC_IS_BIT_SET(tmp, i))
                    {
                        CTC_BIT_SET(oam_data[2], (8 - i - 1));
                    }
                    else
                    {
                        CTC_BIT_UNSET(oam_data[2], (8 - i - 1));
                    }
                }
                tmp = oam_data[3];/*data2*/
                oam_data[3] = (tmp << 2) + ((tmp >> 7)&0x1) + (((tmp >> 6)&0x1) << 1);
            }
            sal_memcpy(event.event_entry[event.valid_num].oam_data, oam_data, sizeof(oam_data));
        }
        event.valid_num++;
        SE_OAM_UNLOCK(lchip);
        if (event.valid_num >= CTC_SC_OAM_EVENT_MAX_NUM)
        {
            SE_OAM_CB_LOCK(lchip);
            se_oam_cb(gchip, &event);
            event.valid_num = 0;
            SE_OAM_CB_UNLOCK(lchip);
        }
    }
    if (event.valid_num > 0)
    {
        SE_OAM_CB_LOCK(lchip);
        se_oam_cb(gchip, &event);
        event.valid_num = 0;
        SE_OAM_CB_UNLOCK(lchip);
    }

    goto RETURN;
error_proc:
    SE_OAM_UNLOCK(lchip);
RETURN:

    return ret;
}
#if defined E_UNIT && (FEATURE_MODE == 0)
int32
sys_usw_aps_isr(uint8 lchip, uint8 isr_type, void* p_data)
{
    sys_usw_eunit_isr_data_t* isr_data = (sys_usw_eunit_isr_data_t*)p_data;
    CTC_INTERRUPT_EVENT_FUNC se_oam_cb = NULL;
    ctc_sc_oam_event_t* event = NULL;
    uint8 aps_gp_id = 0;
    uint8 gchip = 0;
    uint8 i =0;
    uint32 cmd = 0;
    uint8 tmp_gp_id = 0;
    uint32 aps_grp_addr =0;
    sys_sc_oam_mep_t* mep_db=NULL;
    sys_sc_oam_mep_t* work_mep_db=NULL;
    g8031_aps_group_t aps_grop[SYS_APS_GRP_NUM + 1];
    uint8 grp_word = sizeof(aps_grop) / 4;
    uint8 is_aps_defect = 0;
    SYS_SC_OAM_INIT_CHECK(lchip);
    sal_memset(aps_grop, 0, sizeof(aps_grop));
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "Intr id is %d\n", isr_data->irq_id);
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_SC_OAM, &se_oam_cb));
    if (!se_oam_cb)
    {
        return CTC_E_NOT_INIT;
    }
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    
    /*read db from ecpu*/
    cmd = DRV_IOR(MiscIntInfo6_t, MiscIntInfo6_miscIntInfo6_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &aps_grp_addr));

    for (i = 0; i <  grp_word / SYS_APS_GRP_READ_SIZE; i++)
    {
        drv_usw_chip_read_ext(lchip, aps_grp_addr + i*4*SYS_APS_GRP_READ_SIZE, (uint32*)aps_grop + SYS_APS_GRP_READ_SIZE*i, SYS_APS_GRP_READ_SIZE );
    }
    if (grp_word % SYS_APS_GRP_READ_SIZE)
    {
        drv_usw_chip_read_ext(lchip, aps_grp_addr + i*4*SYS_APS_GRP_READ_SIZE, (uint32*)aps_grop + SYS_APS_GRP_READ_SIZE*i,  grp_word % SYS_APS_GRP_READ_SIZE);
    }
    SE_OAM_LOCK(lchip);


    switch (isr_data->irq_id)
    {
        case SYS_EUNIT_ISR_G8031_MIS_GRP0:
        case SYS_EUNIT_ISR_G8031_STATE_CHANGE_GRP0:
        case SYS_EUNIT_ISR_G8031_STATE_APS_SWITCH_GRP0:
            tmp_gp_id = 1;
            break;
        case SYS_EUNIT_ISR_G8031_MIS_GRP1:
        case SYS_EUNIT_ISR_G8031_STATE_CHANGE_GRP1:
        case SYS_EUNIT_ISR_G8031_STATE_APS_SWITCH_GRP1:
            tmp_gp_id = 21;
            break;
        case SYS_EUNIT_ISR_G8031_MIS_GRP2:
        case SYS_EUNIT_ISR_G8031_STATE_CHANGE_GRP2:
        case SYS_EUNIT_ISR_G8031_STATE_APS_SWITCH_GRP2:
            tmp_gp_id = 41;
            break;
         default:
            break;
        }

        MALLOC_ZERO(MEM_OAM_MODULE, event, sizeof(ctc_sc_oam_event_t));
        
        if(NULL == event)
        {
            SE_OAM_UNLOCK(lchip);
            return CTC_E_NO_MEMORY;
        }
        
        for (aps_gp_id = tmp_gp_id; aps_gp_id <  tmp_gp_id + SYS_APS_GRP_SYNC_NUM; aps_gp_id++)
        {
            if (!aps_grop[aps_gp_id].enable)
            {
                continue;
            }
            mep_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip, aps_grop[aps_gp_id].protection_path);
            work_mep_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip, aps_grop[aps_gp_id].working_path);
            if (!mep_db || !work_mep_db)
            {
                continue;
            }
            _sys_usw_sc_oam_get_defect_bmp(lchip, mep_db, &(event->event_entry[event->valid_num].defect_bmp));
            event->event_entry[event->valid_num].event_type = CTC_SC_OAM_EVENT_TYPE_DEFECT;
            if (aps_grop[aps_gp_id].aps_mismatch)
            {
                CTC_SET_FLAG(event->event_entry[event->valid_num].defect_bmp, CTC_SC_OAM_DEFECT_APS_MISMATCH);
                is_aps_defect = 1;
            }
            if (aps_grop[aps_gp_id].active_path != g_sc_oam_master[lchip]->aps_group[aps_gp_id].active_path)
            {
                CTC_SET_FLAG(event->event_entry[event->valid_num].defect_bmp, CTC_SC_OAM_DEFECT_APS_PATH_SWITCH);
                is_aps_defect = 1;
            }
            if (aps_grop[aps_gp_id].current_state != g_sc_oam_master[lchip]->aps_group[aps_gp_id].current_state)
            {
                CTC_SET_FLAG(event->event_entry[event->valid_num].defect_bmp, CTC_SC_OAM_DEFECT_APS_STATE_CHANGE);
                is_aps_defect = 1;
            }
            if (event->event_entry[event->valid_num].defect_bmp && is_aps_defect)
            {
                event->event_entry[event->valid_num].client_id = mep_db->client_id;
                event->valid_num++;
                is_aps_defect = 0;
            }
            mep_db->aps_info.protection_type = (aps_grop[aps_gp_id].aps_channel << 3) + ((!aps_grop[aps_gp_id].bridge_permanent) << 2) + (aps_grop[aps_gp_id].direction << 1) + aps_grop[aps_gp_id].is_revertive;
            work_mep_db->aps_info.protection_type = (aps_grop[aps_gp_id].aps_channel << 3) + ((!aps_grop[aps_gp_id].bridge_permanent) << 2) + (aps_grop[aps_gp_id].direction << 1) + aps_grop[aps_gp_id].is_revertive;
        }
        sal_memcpy(&g_sc_oam_master[lchip]->aps_group[tmp_gp_id], aps_grop + tmp_gp_id, sizeof(g8031_aps_group_t)*SYS_APS_GRP_SYNC_NUM);
        SE_OAM_UNLOCK(lchip);

        if (event->valid_num > 0)/*SYS_APS_GRP_SYNC_NUM must <= CTC_SC_OAM_EVENT_MAX_NUM !!!*/
        {
            SE_OAM_CB_LOCK(lchip);
            se_oam_cb(gchip, event);
            event->valid_num = 0;
            SE_OAM_CB_UNLOCK(lchip);
        }

    mem_free(event);

    return CTC_E_NONE;
}
#endif
int32
sys_usw_sc_oam_isr_defect(uint8 lchip, uint32 intr, void* p_data)
{
    uint8 gchip = 0;
    ctc_sc_oam_event_t event;
    CTC_INTERRUPT_EVENT_FUNC sc_oam_cb = NULL;
    int32 ret = CTC_E_NONE;
    uint32 do_intr_cnt =0;
    uint32 do_intr_num = SYS_SC_CLIENT_ID_NUM;
    uint32 cmd =0;
    uint32 mep_bitmap[sizeof(FlexEOamDefectBitmapM_m)/4]={0};
    DsFlexEMep_m mep;
    DsFlexEMep_m mep_mask;
    FlexEOamDefectBitmapM_m defect_bmp;
    sys_sc_oam_mep_t* oam_db=NULL;
    SYS_SC_OAM_INIT_CHECK(lchip);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&event, 0, sizeof(ctc_sc_oam_event_t));
    sal_memset(&defect_bmp, 0, sizeof(defect_bmp));
    sal_memset(&mep, 0 , sizeof(mep));
    sal_memset(&mep_mask, 0xFF , sizeof(mep_mask));
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));

    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_SC_OAM, &sc_oam_cb));
    if (!sc_oam_cb)
    {
        return CTC_E_NOT_INIT;
    }

    /* 1. read  mepbitmap */

    SE_OAM_LOCK(lchip);
    cmd = DRV_IOR(FlexEOamDefectBitmapM_t,   DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &defect_bmp), ret, End);
    GetFlexEOamDefectBitmapM(A, mepBitmapM_f, &defect_bmp, mep_bitmap);

    for (do_intr_cnt = 0; do_intr_cnt < do_intr_num; do_intr_cnt++)
    {
        if (CTC_BMP_ISSET(mep_bitmap, do_intr_cnt))
        {
            oam_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip,do_intr_cnt);
            if (!oam_db)
            {
                continue;
            }
            event.event_entry[event.valid_num].event_type = CTC_SC_OAM_EVENT_TYPE_DEFECT;
            event.event_entry[event.valid_num].client_id =oam_db->client_id;
            _sys_usw_sc_oam_get_defect_bmp(lchip, oam_db, &(event.event_entry[event.valid_num].defect_bmp));
            if (event.event_entry[event.valid_num].defect_bmp == 0xFFFFFFFF)
            {
                continue;
            }
            if (CTC_FLAG_ISSET(event.event_entry[event.valid_num].defect_bmp, CTC_SC_OAM_DEFECT_CS_TYPE_CHK))/*When received a cs type check fail packet,will reply a cs type packet in 1 second */
            {
                cmd = DRV_IOR(DsFlexEMep_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, do_intr_cnt, cmd, &mep),ret,End);
                SetDsFlexEMep(V, csTxWhile_f, &mep, 0);
                SetDsFlexEMep(V, csTxWhile_f, &mep_mask, 0);
                CTC_ERROR_GOTO(_sys_usw_sc_oam_write_by_acc(lchip, do_intr_cnt, &mep, &mep_mask),ret,End);
            }
            event.valid_num++;
            if (event.valid_num >= CTC_SC_OAM_EVENT_MAX_NUM)
            {
                SE_OAM_UNLOCK(lchip);
                SE_OAM_CB_LOCK(lchip);
                sc_oam_cb(gchip, &event);
                SE_OAM_CB_UNLOCK(lchip);
                SE_OAM_LOCK(lchip);
                event.valid_num = 0;
            }
        }
    }

    if (event.valid_num >0)
    {
        SE_OAM_UNLOCK(lchip);
        SE_OAM_CB_LOCK(lchip);
        sc_oam_cb(gchip, &event);
        SE_OAM_CB_UNLOCK(lchip);
        SE_OAM_LOCK(lchip);
        event.valid_num = 0;
    }

End:
    SE_OAM_UNLOCK(lchip);
    return CTC_E_NONE;
}
int32
sys_usw_sc_oam_add_mep(uint8 lchip, ctc_sc_oam_mep_t* p_mep)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    ctc_sc_oam_mep_t mep;
    uint32 tmp_value = 1;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep);

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep->client_id);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "flag            = 0x%x\n", p_mep->flag);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_speed    = %d\n",   p_mep->client_speed);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "rx_en_bmp       = 0x%x\n", p_mep->rx_en_bmp);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "tx_en_bmp       = 0x%x\n", p_mep->tx_en_bmp);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_rx_period   = %d\n",   p_mep->bas_rx_period);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_tx_period   = %d\n",   p_mep->bas_tx_period);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_seq_mode    = %d\n",   p_mep->bas_seq_mode);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_seq         = %d\n",   p_mep->bas_seq);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cv_interval     = %d\n",   p_mep->cv_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "one_dm_interval = %d\n",   p_mep->one_dm_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "two_dm_interval = %d\n",   p_mep->two_dm_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cs_interval     = %d\n",   p_mep->cs_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cs_type         = %d\n",   p_mep->cs_type);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "aps_interval    = %d\n",   p_mep->aps_interval);

    CTC_ERROR_RETURN(_sys_usw_sc_oam_mep_check(lchip, p_mep));


    SE_OAM_LOCK(lchip);
    /*1. lookup db*/
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep->client_id);
    if (NULL != p_mep_db)
    {
        ret = CTC_E_EXIST;
        goto end;
    }

    /*2. build db*/
    p_mep_db = (sys_sc_oam_mep_t*)mem_malloc(MEM_OAM_MODULE, sizeof(sys_sc_oam_mep_t));
    if(NULL == p_mep_db)
    {
        ret = CTC_E_NO_MEMORY;
        goto end;
    }
    sal_memset(p_mep_db, 0, sizeof(sys_sc_oam_mep_t));
    CTC_ERROR_GOTO(sys_usw_flexe_get_client_property(lchip, p_mep->client_id,
                                                                 SYS_FLEXE_CLIENT_PROP_HW_CLIENT, &p_mep_db->hw_client_id), ret, error0);
    p_mep_db->client_id = p_mep->client_id;
    p_mep_db->client_speed = p_mep->client_speed;
    p_mep_db->bas_tx_period = p_mep->bas_tx_period;
    sal_memcpy(&(p_mep_db->ber_thrd), &(p_mep->ber_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
    sal_memcpy(&(p_mep_db->rei_thrd), &(p_mep->rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP, 1);

    /*3. alloc profile index*/
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_ber_thrd(lchip, &(p_mep_db->ber_id), p_mep_db, 1), ret, error0);
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_ber_thrd(lchip, &(p_mep_db->rei_id), p_mep_db, 0), ret, error1);


    /*4. add to hw*/
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_to_asic(lchip, p_mep_db, p_mep, 0), ret, error2);

    /*5. add to db*/
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_to_db(lchip, p_mep_db), ret, error3);

    CTC_ERROR_GOTO(sys_usw_flexe_set_client_property(lchip, p_mep->client_id,
                                                                 SYS_FLEXE_CLIENT_PROP_BIND_OAM, &tmp_value), ret, error3);
    sal_memset(&(g_sc_oam_master[lchip]->mep_defect_bitmap[p_mep_db->hw_client_id]), 0, sizeof(uint32));

    SE_OAM_UNLOCK(lchip);
    return CTC_E_NONE;

error3:
    sal_memset(&mep, 0, sizeof(ctc_sc_oam_mep_t));
    _sys_usw_sc_oam_add_to_asic(lchip, p_mep_db, &mep, 1);
error2:
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db,0);
error1:
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db,1);
error0:
    mem_free(p_mep_db);
end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}
int32
sys_usw_sc_oam_remove_mep(uint8 lchip, ctc_sc_oam_mep_t* p_mep)
{
    int32 ret = CTC_E_NONE;
    ctc_sc_oam_mep_t mep;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    uint32 tmp_value = 0;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep->client_id);
    SE_OAM_LOCK(lchip);
    /*1. lookup db*/
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep->client_id);
    if (NULL == p_mep_db)
    {
        ret =  CTC_E_NOT_EXIST;
        goto end;
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP, 1);

    sys_usw_flexe_set_client_property(lchip, p_mep->client_id, SYS_FLEXE_CLIENT_PROP_BIND_OAM,  &tmp_value);

    /*2. remove from aps group*/
    if (p_mep_db->aps_info.aps_en)
    {
        _sys_usw_sc_oam_remove_from_aps_grp(lchip, p_mep_db);
        if (0 == p_mep_db->aps_info.is_protection)
        {
            _sys_usw_sc_oam_destroy_aps_grp(lchip, p_mep_db);
        }
    }

    /*3. free profile index*/
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db, 0);
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db, 1);

    /*4. remove hw*/
    sal_memset(&mep, 0, sizeof(ctc_sc_oam_mep_t));
    _sys_usw_sc_oam_add_to_asic(lchip, p_mep_db, &mep, 1);

    /*5. remove db*/
    _sys_usw_sc_oam_del_from_db(lchip, p_mep_db);
    mem_free(p_mep_db);
end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}
int32
sys_usw_sc_oam_update_mep(uint8 lchip, ctc_sc_oam_mep_t* p_mep)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t mep_db_old;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    ctc_sc_oam_mep_info_t mep_info;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep);


    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep->client_id);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "flag            = 0x%x\n", p_mep->flag);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_speed    = %d\n",   p_mep->client_speed);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "rx_en_bmp       = 0x%x\n", p_mep->rx_en_bmp);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "tx_en_bmp       = 0x%x\n", p_mep->tx_en_bmp);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_rx_period   = %d\n",   p_mep->bas_rx_period);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_tx_period   = %d\n",   p_mep->bas_tx_period);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_seq_mode    = %d\n",   p_mep->bas_seq_mode);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "bas_seq         = %d\n",   p_mep->bas_seq);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cv_interval     = %d\n",   p_mep->cv_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "one_dm_interval = %d\n",   p_mep->one_dm_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "two_dm_interval = %d\n",   p_mep->two_dm_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cs_interval     = %d\n",   p_mep->cs_interval);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "cs_type         = %d\n",   p_mep->cs_type);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "aps_interval    = %d\n",   p_mep->aps_interval);

    CTC_ERROR_RETURN(_sys_usw_sc_oam_mep_check(lchip, p_mep));

    SE_OAM_LOCK(lchip);

    /*1. lookup db*/
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep->client_id);
    if (NULL == p_mep_db)
    {
        ret = CTC_E_NOT_EXIST;
        goto end;
    }
    sal_memset(&mep_db_old, 0, sizeof(sys_sc_oam_mep_t));
    sal_memcpy(&mep_db_old, p_mep_db, sizeof(sys_sc_oam_mep_t));
    sal_memset(&mep_info, 0, sizeof(ctc_sc_oam_mep_info_t));

    p_mep_db->client_speed = p_mep->client_speed;
    p_mep_db->bas_tx_period = p_mep->bas_tx_period;
    sal_memcpy(&(p_mep_db->ber_thrd), &(p_mep->ber_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
    sal_memcpy(&(p_mep_db->rei_thrd), &(p_mep->rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));

    /*2. alloc new profile index*/
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP, 1);
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_ber_thrd(lchip, &(p_mep_db->ber_id), p_mep_db, 1), ret, error0);
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_ber_thrd(lchip, &(p_mep_db->rei_id), p_mep_db, 0), ret, error1);

    /*3. update hw*/
    p_mep_db->client_speed = p_mep->client_speed;
    CTC_ERROR_GOTO(_sys_usw_sc_oam_add_to_asic(lchip, p_mep_db, p_mep, 0), ret, error2);

    /*4. free old profile*/
    _sys_usw_sc_oam_remove_ber_thrd(lchip, &mep_db_old, 0);
    _sys_usw_sc_oam_remove_ber_thrd(lchip, &mep_db_old, 1);

    SE_OAM_UNLOCK(lchip);
    return CTC_E_NONE;

error2:
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db, 0);
error1:
    _sys_usw_sc_oam_remove_ber_thrd(lchip, p_mep_db, 1);
error0:
    sal_memcpy(p_mep_db, &mep_db_old, sizeof(sys_sc_oam_mep_t));
end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_sc_oam_get_mep(uint8 lchip, ctc_sc_oam_mep_t* p_mep)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t* p_mep_db = NULL;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep->client_id);
    SE_OAM_LOCK(lchip);
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep->client_id);
    if (NULL == p_mep_db)
    {
        ret = CTC_E_NOT_EXIST;
        goto end;
    }
    CTC_ERROR_GOTO(_sys_usw_sc_oam_dump_config(lchip, p_mep_db, p_mep), ret, end);

end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_sc_oam_set_mep_property(uint8 lchip, ctc_sc_oam_mep_prop_t* p_mep_prop)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t* p_mep_db = NULL;
    sys_sc_oam_mep_t mep_db_old;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep_prop);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep_prop->client_id);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "prop_type       = %d\n",   p_mep_prop->prop_type);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "update_value    = %d\n",   p_mep_prop->update_value);
    CTC_ERROR_RETURN(_sys_usw_sc_oam_mep_prop_check(lchip, p_mep_prop));

    SE_OAM_LOCK(lchip);
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep_prop->client_id);
    if (NULL == p_mep_db)
    {
        ret = CTC_E_NOT_EXIST;
        goto end;
    }
    sal_memcpy(&mep_db_old, p_mep_db, sizeof(sys_sc_oam_mep_t));
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP, 1);
    CTC_ERROR_GOTO(_sys_usw_sc_oam_set_to_asic(lchip, p_mep_db, p_mep_prop), ret, end);

    SE_OAM_UNLOCK(lchip);
    return CTC_E_NONE;

end:
    if (p_mep_db != NULL)
    {
        sal_memcpy(p_mep_db, &mep_db_old, sizeof(sys_sc_oam_mep_t));
    }
    SE_OAM_UNLOCK(lchip);
    return ret;

}

int32
sys_usw_sc_oam_get_mep_property(uint8 lchip, ctc_sc_oam_mep_prop_t* p_mep_prop)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t* p_mep_db = NULL;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep_prop);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep_prop->client_id);

    SE_OAM_LOCK(lchip);
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep_prop->client_id);
    if (NULL == p_mep_db)
    {
        ret = CTC_E_NOT_EXIST;
        goto end;
    }
    CTC_ERROR_GOTO(_sys_usw_sc_oam_get_from_asic(lchip, p_mep_db, p_mep_prop), ret, end);
end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_sc_oam_get_mep_info(uint8 lchip, ctc_sc_oam_mep_info_t* p_mep_info)
{
    int32 ret = CTC_E_NONE;
    sys_sc_oam_mep_t* p_mep_db = NULL;

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mep_info);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "client_id       = %d\n",   p_mep_info->client_id);
    SE_OAM_LOCK(lchip);
    p_mep_db = _sys_usw_sc_oam_lkup(lchip, p_mep_info->client_id);
    if (NULL == p_mep_db)
    {
        ret = CTC_E_NOT_EXIST;
        goto end;
    }
    CTC_ERROR_GOTO(_sys_usw_sc_oam_dump_state(lchip, p_mep_db, p_mep_info), ret, end);

end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_sc_oam_set_property(uint8 lchip, ctc_sc_oam_prop_t* p_prop)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 rx_defect_vector[2] = {0};
    uint32 old_defect_vector[2] = {0};
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_prop);

    SE_OAM_LOCK(lchip);

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "prop_type       = %d\n",   p_prop->prop_type);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "value           = %d\n",   p_prop->value);
    switch (p_prop->prop_type)
    {
        case CTC_SC_OAM_PROP_DEFECT_TO_CPU:
            {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, old_defect_vector), ret, end);
                if (CTC_BMP_ISSET(old_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX)))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));
                }
                if (CTC_BMP_ISSET(old_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU)))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU));
                }
                if (CTC_BMP_ISSET(old_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU)))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU));
                }
                _sys_usw_sc_oam_map_defect(lchip, SYS_DEFECT_TYPE_RX, p_prop->value, rx_defect_vector, 0);
                cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
                rx_defect_vector[0] = 0;
                _sys_usw_sc_oam_map_defect(lchip, SYS_DEFECT_TYPE_UPDATE, p_prop->value, rx_defect_vector, 0);
                cmd = DRV_IOW(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
            }
            break;
        case CTC_SC_OAM_PROP_DEFECT_TO_RDI:
            {
                uint8 i=0;
                uint32 rdi_bmp=0;
                uint32 rdi_clear[] = {
                    CTC_SC_OAM_DEFECT_DLOC,
                    CTC_SC_OAM_DEFECT_CS_TYPE_CHK,
                    CTC_SC_OAM_DEFECT_DAPI_CHK,
                    CTC_SC_OAM_DEFECT_SAPI_CHK,
                    CTC_SC_OAM_DEFECT_DDEG_REI,
                    CTC_SC_OAM_DEFECT_DEXC_REI,
                    CTC_SC_OAM_DEFECT_DDEG,
                    CTC_SC_OAM_DEFECT_DEXC
                    };
                if ((CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_DEFECT_FIRST_RX)) ||(CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_DEFECT_RDI)))
                {
                    ret = CTC_E_INVALID_PARAM;
                    goto end;
                }
                _sys_usw_sc_oam_map_defect(lchip, SYS_DEFECT_TYPE_RX, p_prop->value, rx_defect_vector, 1);
                cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportRdiEn_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);

                value = CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_DEFECT_DLOC);
                cmd = DRV_IOW(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_dlocTriggerRdi_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, end);

                for (i = 0; i < sizeof(rdi_clear)/sizeof(rdi_clear[0]); i++)
                {
                    if (CTC_FLAG_ISSET(p_prop->value, rdi_clear[i]))
                    {
                        CTC_BIT_SET(rdi_bmp, i);
                    }
                }
                cmd = DRV_IOW(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_failToRdiVec_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &rdi_bmp), ret, end);
            }
            break;
        case CTC_SC_OAM_PROP_DEFECT_TO_APS_SWTICH:
           {
                if (! g_sc_oam_master[lchip]->hw_aps)
                {
                    ret = CTC_E_INVALID_PARAM;
                    goto end;
                }
                CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));
                _sys_usw_sc_oam_map_defect(lchip, SYS_DEFECT_TYPE_RX, p_prop->value, rx_defect_vector, 0);
                cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriL_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);

                sal_memset(rx_defect_vector,0,sizeof(rx_defect_vector));
                _sys_usw_sc_oam_map_defect(lchip, SYS_DEFECT_TYPE_UPDATE, p_prop->value, rx_defect_vector, 0);
                cmd = DRV_IOW(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_defectReportDmaPriL_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
            }
            break;
        case CTC_SC_OAM_PROP_HW_APS_SWTICH:
            {
                SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MASTER, 1);
                g_sc_oam_master[lchip]->hw_aps = p_prop->value? 1 : 0;
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriL_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
                if (p_prop->value)
                {
                    /*Hw aps  need to send aps packets to LCPU*/
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));
                }
                else
                {
                    CTC_BMP_UNSET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));

                }
                cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriL_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
            }
            break;
        case CTC_SC_OAM_PROP_EVENT_TO_CPU:
            {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
                if (CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_EVENT_TYPE_APS_RX))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));
                    value = 1;
                    cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_ignoreApsRxCpuCtl_f);
                    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, end);
                }
                else
                {
                    CTC_BMP_UNSET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX));
                }
                if (CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_EVENT_TYPE_OTHER_PDU))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU));
                }
                else
                {
                    CTC_BMP_UNSET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU));
                }
                if (CTC_FLAG_ISSET(p_prop->value, CTC_SC_OAM_EVENT_TYPE_INVALID_PDU))
                {
                    CTC_BMP_SET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU));
                }
                else
                {
                    CTC_BMP_UNSET(rx_defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU));
                }
                cmd = DRV_IOW(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, rx_defect_vector), ret, end);
            }
            break;

        default:
            ret = CTC_E_INVALID_PARAM;
            goto end;
            break;
    }

end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_sc_oam_wb_sync(uint8 lchip, uint32 app_id)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_data_t wb_data = {0};
    sys_wb_sc_oam_master_t* p_wb_sc_oam_master = NULL;
    sys_traverse_t  wb_sc_oam_traverse = {0};
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);
    sal_memset(&wb_sc_oam_traverse, 0, sizeof(sys_traverse_t));
    /*syncup  sc oam matser*/
    SE_OAM_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SC_OAM_SUBID_MASTER)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_sc_oam_master_t, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MASTER);

        p_wb_sc_oam_master = (sys_wb_sc_oam_master_t  *)wb_data.buffer;
        p_wb_sc_oam_master->lchip = lchip;
        p_wb_sc_oam_master->version = SYS_WB_VERSION_SC_OAM;
        p_wb_sc_oam_master->hw_aps = g_sc_oam_master[lchip]->hw_aps;
        sal_memcpy(p_wb_sc_oam_master->rx_defect_vector, g_sc_oam_master[lchip]->rx_defect_vector, sizeof(p_wb_sc_oam_master->rx_defect_vector));
        sal_memcpy(p_wb_sc_oam_master->update_defect_vector, g_sc_oam_master[lchip]->update_defect_vector, sizeof(p_wb_sc_oam_master->update_defect_vector));
        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MASTER);
    }

    /*syncup  sc oam mep*/
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SC_OAM_SUBID_MEP)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_sc_oam_mep_t, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP);
        wb_sc_oam_traverse.data = &wb_data;
        wb_sc_oam_traverse.value1 = lchip;
        ctc_hash_traverse(g_sc_oam_master[lchip]->hash_mep, (hash_traversal_fn)_sys_usw_sc_oam_wb_traverse_sync_node, (void*)&wb_sc_oam_traverse);

        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP);
    }

    done:
    CTC_WB_FREE_BUFFER(wb_data.buffer);
    SE_OAM_UNLOCK(lchip);

    return ret;
}

int32
_sys_usw_sc_oam_wb_init(uint8 lchip)
{
   ctc_wb_appid_t  appid;
   sal_memset(&appid,0,sizeof(appid));

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MASTER) ;
   appid.entry_num = 1;
   appid.entry_size  = sizeof(sys_wb_sc_oam_master_t);
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP) ;
   appid.entry_num = SYS_APS_GRP_NUM*2;
   appid.entry_size  = sizeof(sys_wb_sc_oam_mep_t);
   ctc_wb_add_appid( lchip, &appid);

   return 0;
}


int32
sys_usw_sc_oam_wb_restore(uint8 lchip)
{
    int32 ret=0;
    uint8 i=0;
    uint8 entry_cnt = 0;
    uint32 cmd=0;
    uint32 aps_grp_addr=0;
    sys_usw_opf_t opf;
    ctc_wb_query_t wb_query;
    sys_wb_sc_oam_master_t sc_oam_master;
    sys_wb_sc_oam_mep_t sc_oam_mep;
    sys_sc_oam_mep_t* p_mep_db=NULL;
    sys_sc_oam_ber_t thrd;
    sys_sc_oam_ber_t* thrd_db = NULL;
    ctc_spool_t* spool = NULL;
    uint32 total_size = (SYS_APS_GRP_NUM+1)*sizeof(g8031_aps_group_t)/4;
    sal_memset(&sc_oam_master, 0, sizeof(sc_oam_master));
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    sal_memset(&thrd, 0, sizeof(sys_sc_oam_ber_t));
    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);


    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    /*restore  sc oam_master*/
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_sc_oam_master_t, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MASTER);
    CTC_ERROR_GOTO(ctc_wb_query_entry(&wb_query), ret, done);
    sal_memcpy(&sc_oam_master, wb_query.buffer,  wb_query.key_len + wb_query.data_len);
    g_sc_oam_master[lchip]->hw_aps = sc_oam_master.hw_aps;
    sal_memcpy(g_sc_oam_master[lchip]->rx_defect_vector,sc_oam_master.rx_defect_vector,sizeof(sc_oam_master.rx_defect_vector));
    sal_memcpy(g_sc_oam_master[lchip]->update_defect_vector,sc_oam_master.update_defect_vector,sizeof(sc_oam_master.update_defect_vector));

    /*restore aps group states from ECPU*/
    if (g_sc_oam_master[lchip]->hw_aps)
    {
        cmd = DRV_IOR(MiscIntInfo6_t, MiscIntInfo6_miscIntInfo6_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &aps_grp_addr));
        for (i = 0; i <  total_size / SYS_APS_GRP_READ_SIZE; i++)
        {
            drv_usw_chip_read_ext(lchip, aps_grp_addr + i*4*SYS_APS_GRP_READ_SIZE,
                (uint32*)g_sc_oam_master[lchip]->aps_group + SYS_APS_GRP_READ_SIZE*i, SYS_APS_GRP_READ_SIZE);
        }
        if (total_size % SYS_APS_GRP_READ_SIZE)
        {
            drv_usw_chip_read_ext(lchip, aps_grp_addr + i*4*SYS_APS_GRP_READ_SIZE,
                (uint32*)g_sc_oam_master[lchip]->aps_group + SYS_APS_GRP_READ_SIZE*i,  (total_size % SYS_APS_GRP_READ_SIZE));
        }

        for (i = 0; i < SYS_APS_GRP_NUM; i++)
        {
            if (g_sc_oam_master[lchip]->aps_group[i].enable)
            {
                g_sc_oam_master[lchip]->aps_grp_cnt++;
            }
        }
    }

      /*restore  scoam mep*/
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_sc_oam_mep_t, CTC_FEATURE_SC_OAM, SYS_WB_APPID_SC_OAM_SUBID_MEP);
    sal_memset(&sc_oam_mep, 0, sizeof(sys_wb_sc_oam_mep_t));

    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
    sal_memcpy(&sc_oam_mep, (sys_wb_sc_oam_mep_t *)wb_query.buffer+entry_cnt,  wb_query.key_len + wb_query.data_len);
    entry_cnt++;

    /*client: lookup, build node and add to DB*/
    if (NULL == ctc_hash_lookup(g_sc_oam_master[lchip]->hash_mep, &sc_oam_mep))
    {
        p_mep_db = (sys_sc_oam_mep_t*)mem_malloc(MEM_OAM_MODULE, sizeof(sys_sc_oam_mep_t));
        if (NULL == p_mep_db)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_mep_db,0,sizeof(sys_sc_oam_mep_t));
        p_mep_db->client_id = sc_oam_mep.client_id;
        p_mep_db->hw_client_id = sc_oam_mep.hw_client_id;
        p_mep_db->aps_grp_id = sc_oam_mep.aps_grp_id;
        p_mep_db->bas_tx_period = sc_oam_mep.bas_tx_period;
        p_mep_db->client_speed = sc_oam_mep.client_speed;
        p_mep_db->aps_info.aps_en = g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].enable;
        p_mep_db->aps_info.is_protection = (p_mep_db->hw_client_id==g_sc_oam_master[lchip]->aps_group[p_mep_db->aps_grp_id].working_path)?0:1;

        /*restore rei and ber thrd*/
        _sys_usw_sc_oam_wb_mapping(lchip,sc_oam_mep.client_id,p_mep_db);

        thrd.period = _sys_usw_sc_oam_map_bas_period(lchip, p_mep_db->bas_tx_period, 0) + 1;
        thrd.index.index = sc_oam_mep.ber_index;
        sal_memcpy(&thrd.thrd, &(p_mep_db->ber_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
        spool = g_sc_oam_master[lchip]->spool_ber;
        CTC_ERROR_GOTO(ctc_spool_add(spool, &thrd, NULL, &thrd_db),ret,done);

        thrd.index.index = sc_oam_mep.rei_index;
        spool =  g_sc_oam_master[lchip]->spool_rei;
        sal_memcpy(&thrd.thrd, &(p_mep_db->rei_thrd), sizeof(ctc_sc_oam_ber_thrd_t));
        CTC_ERROR_GOTO(ctc_spool_add(spool, &thrd, NULL, &thrd_db),ret,done);

        if (NULL == ctc_hash_insert(g_sc_oam_master[lchip]->hash_mep, p_mep_db))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        if (p_mep_db->aps_grp_id != 0)
        {
            opf.pool_type = g_sc_oam_master[lchip]->opf_type;
            opf.pool_index = SYS_SC_OAM_OPF_TYPE_APS_GRP;
            sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_mep_db->aps_grp_id);
        }
    }
        CTC_WB_QUERY_ENTRY_END((&wb_query));
    done:
        CTC_WB_FREE_BUFFER(wb_query.buffer);
        return ret;

}

int32
sys_usw_sc_oam_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param)
{
    uint32 loop = 0;
    sys_traverse_t sc_oam_dump_traverse;
    sal_memset(&sc_oam_dump_traverse,0,sizeof(sys_traverse_t));
    SYS_SC_OAM_INIT_CHECK(lchip);
    SE_OAM_LOCK(lchip);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# SC OAM");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%-30s:", "rx_defect_vector");

    for (loop = 0; loop < 2; loop++)
    {
        SYS_DUMP_DB_LOG(p_f, "[%u:0x%x]", loop, g_sc_oam_master[lchip]->rx_defect_vector[loop]);
    }
    SYS_DUMP_DB_LOG(p_f, "\n");
    SYS_DUMP_DB_LOG(p_f, "%-30s:", "update_defect_vector");
    for (loop = 0; loop < 2; loop++)
    {
        SYS_DUMP_DB_LOG(p_f, "[%u:0x%x]", loop, g_sc_oam_master[lchip]->update_defect_vector[loop]);
    }
    SYS_DUMP_DB_LOG(p_f, "\n%-30s:%s\n", "hw_aps", g_sc_oam_master[lchip]->hw_aps ? "Y" : "N");
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "aps_grp_cnt", g_sc_oam_master[lchip]->aps_grp_cnt);

    for (loop = 0; loop < SYS_APS_GRP_NUM + 1; loop++)
    {
        if (g_sc_oam_master[lchip]->aps_group[loop].enable)
        {
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "Aps Group :", loop);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " aps_channel", g_sc_oam_master[lchip]->aps_group[loop].aps_channel);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " bridge_permanent", g_sc_oam_master[lchip]->aps_group[loop].bridge_permanent);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " direction", g_sc_oam_master[lchip]->aps_group[loop].direction);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " is_revertive", g_sc_oam_master[lchip]->aps_group[loop].is_revertive);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " requested_signal", g_sc_oam_master[lchip]->aps_group[loop].requested_signal);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " bridged_signal", g_sc_oam_master[lchip]->aps_group[loop].bridged_signal);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " current_state", g_sc_oam_master[lchip]->aps_group[loop].current_state);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " is_protection", g_sc_oam_master[lchip]->aps_group[loop].is_protection);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " current_event", g_sc_oam_master[lchip]->aps_group[loop].current_event);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " aps_grp_id", g_sc_oam_master[lchip]->aps_group[loop].aps_grp_id);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " wtr_timer", g_sc_oam_master[lchip]->aps_group[loop].wtr_timer);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " wtr_while", g_sc_oam_master[lchip]->aps_group[loop].wtr_while);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " working_path", g_sc_oam_master[lchip]->aps_group[loop].working_path);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " protection_path", g_sc_oam_master[lchip]->aps_group[loop].protection_path);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " active_path", g_sc_oam_master[lchip]->aps_group[loop].active_path);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " local_freeze", g_sc_oam_master[lchip]->aps_group[loop].local_freeze);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " local_lockout", g_sc_oam_master[lchip]->aps_group[loop].local_lockout);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " far_end_last_state", g_sc_oam_master[lchip]->aps_group[loop].far_end_last_state);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " aps_mismatch", g_sc_oam_master[lchip]->aps_group[loop].aps_mismatch);
            SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", " reassert_req", g_sc_oam_master[lchip]->aps_group[loop].reassert_req);
        }
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%s\n", "Mep config:");
    SYS_DUMP_DB_LOG(p_f, "%-12s%-15s%-15s%-15s\n", "Client_id", "Client_speed", "bas_tx_period", "Aps_grp_id");
    sc_oam_dump_traverse.data = p_f;
    sc_oam_dump_traverse.value1 = lchip;
    ctc_hash_traverse(g_sc_oam_master[lchip]->hash_mep, _sys_usw_sc_oam_dump_db_traverse, &sc_oam_dump_traverse);

    SYS_DUMP_DB_LOG(p_f, "\n");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "\n");
    sys_usw_opf_fprint_alloc_used_info(lchip, g_sc_oam_master[lchip]->opf_type, p_f);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    SE_OAM_UNLOCK(lchip);
    return CTC_E_NONE;
}

 int32
sys_usw_sc_oam_get_property(uint8 lchip, ctc_sc_oam_prop_t* p_prop)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 defect_vector[2]  = {0};
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_prop);

    SE_OAM_LOCK(lchip);

    switch (p_prop->prop_type)
    {
        case CTC_SC_OAM_PROP_DEFECT_TO_CPU:
            {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                _sys_usw_sc_oam_unmap_defect(lchip, SYS_DEFECT_TYPE_RX, defect_vector, &p_prop->value);
                cmd = DRV_IOR(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_defectReportDmaPriM_f);
                defect_vector[1] = 0;
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                _sys_usw_sc_oam_unmap_defect(lchip, SYS_DEFECT_TYPE_UPDATE, defect_vector, &p_prop->value);
            }
            break;
        case CTC_SC_OAM_PROP_DEFECT_TO_RDI:
            {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportRdiEn_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                _sys_usw_sc_oam_unmap_defect(lchip, SYS_DEFECT_TYPE_RX, defect_vector, &p_prop->value);
                cmd = DRV_IOR(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_dlocTriggerRdi_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, end);
                if (1 == value)
                {
                    CTC_SET_FLAG(p_prop->value, CTC_SC_OAM_DEFECT_DLOC);
                }
            }
            break;
        case CTC_SC_OAM_PROP_DEFECT_TO_APS_SWTICH:
           {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriL_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                _sys_usw_sc_oam_unmap_defect(lchip, SYS_DEFECT_TYPE_RX, defect_vector, &p_prop->value);
                cmd = DRV_IOR(FlexEOamUpdateCtl_t, FlexEOamUpdateCtl_defectReportDmaPriL_f);
                defect_vector[1] = 0;
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                _sys_usw_sc_oam_unmap_defect(lchip, SYS_DEFECT_TYPE_UPDATE, defect_vector, &p_prop->value);
            }
            break;
        case CTC_SC_OAM_PROP_HW_APS_SWTICH:
            p_prop->value = g_sc_oam_master[lchip]->hw_aps;
            break;
        case CTC_SC_OAM_PROP_EVENT_TO_CPU:
            {
                cmd = DRV_IOR(FlexEOamRxProcCtl_t, FlexEOamRxProcCtl_defectReportDmaPriM_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, defect_vector), ret, end);
                if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_APSRX)))
                {
                    CTC_SET_FLAG(p_prop->value, CTC_SC_OAM_EVENT_TYPE_APS_RX);
                }
                if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_OTHERPDU)))
                {
                    CTC_SET_FLAG(p_prop->value, CTC_SC_OAM_EVENT_TYPE_OTHER_PDU);
                }
                if (CTC_BMP_ISSET(defect_vector, DRV_ENUM(DRV_FLEXEOAMDEFECTTYPE_INVALIDPDU)))
                {
                    CTC_SET_FLAG(p_prop->value, CTC_SC_OAM_EVENT_TYPE_INVALID_PDU);
                }
            }
            break;

        default:
            ret = CTC_E_INVALID_PARAM;
            goto end;
            break;
    }

end:
    SE_OAM_UNLOCK(lchip);
    return ret;
}

 int32
_sys_usw_sc_oam_build_key(sys_sc_oam_mep_t* p_sys_mep)
{
    return ctc_hash_caculate(sizeof(p_sys_mep->client_id), &(p_sys_mep->client_id));
}

 int32
_sys_usw_sc_oam_cmp(sys_sc_oam_mep_t* store_mep,sys_sc_oam_mep_t* lkup_mep)
{
    if (!store_mep || !lkup_mep)
    {
        return FALSE;
    }
    if (store_mep->client_id == lkup_mep->client_id)
    {
        return TRUE;
    }
    return FALSE;
}


int32
sys_usw_sc_oam_init(uint8 lchip, void* p_cfg)
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf   = {0};
    ctc_spool_t spool;
    LCHIP_CHECK(lchip);

    if (g_sc_oam_master[lchip])
    {
        return CTC_E_NONE;
    }

    g_sc_oam_master[lchip] = (sys_sc_oam_master_t*)mem_malloc(MEM_OAM_MODULE, sizeof(sys_sc_oam_master_t));
    if (NULL == g_sc_oam_master[lchip])
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(g_sc_oam_master[lchip], 0 , sizeof(sys_sc_oam_master_t));


    g_sc_oam_master[lchip]->mep_defect_bitmap = (uint32*)mem_malloc(MEM_OAM_MODULE, sizeof(uint32)*SYS_SC_CLIENT_ID_NUM);
    if (NULL == g_sc_oam_master[lchip]->mep_defect_bitmap)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }
    sal_memset((uint8*)g_sc_oam_master[lchip]->mep_defect_bitmap, 0 , sizeof(uint32)*SYS_SC_CLIENT_ID_NUM);

    g_sc_oam_master[lchip]->hash_mep = ctc_hash_create(12, SYS_SC_CLIENT_ID_NUM / 12,
                                                       (hash_key_fn)_sys_usw_sc_oam_build_key,
                                                       (hash_cmp_fn)_sys_usw_sc_oam_cmp);

    if (NULL == g_sc_oam_master[lchip]->hash_mep)
    {
        ret = CTC_E_NO_MEMORY;
         goto error_proc;
    }

    CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &g_sc_oam_master[lchip]->opf_type,  SYS_SC_OAM_OPF_TYPE_MAX, "opf-sc-oam"), ret, error_proc);
    opf.pool_type = g_sc_oam_master[lchip]->opf_type;
    opf.pool_index = SYS_SC_OAM_OPF_TYPE_APS_GRP;
    CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 1, SYS_APS_GRP_NUM), ret, error_proc);/* 0 is invalid*/

    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = 16;
    spool.max_count = 16;
    spool.user_data_size = sizeof(sys_sc_oam_ber_t);
    spool.key_size = CTC_OFFSET_OF(sys_sc_oam_ber_t, calc_key_len);
    spool.min_index = 0;
    spool.max_index = 15;
    spool.desc = "opf-se-oam-ber";
    g_sc_oam_master[lchip]->spool_ber = ctc_spool_create(&spool);
    if (NULL == g_sc_oam_master[lchip]->spool_ber)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }
    spool.desc = "opf-se-oam-rei";
    g_sc_oam_master[lchip]->spool_rei = ctc_spool_create(&spool);
    if (NULL == g_sc_oam_master[lchip]->spool_rei)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }

    if (CTC_E_NONE != sal_mutex_create(&(g_sc_oam_master[lchip]->mutex)))
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }
    if (CTC_E_NONE != sal_mutex_create(&(g_sc_oam_master[lchip]->p_cb_mutex)))
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }

    CTC_ERROR_GOTO(_sys_usw_sc_oam_register_init(lchip), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_SCOAM_EVENT, sys_usw_sc_oam_sync_data), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_SC_OAM, sys_usw_sc_oam_event_cb), ret, error_proc);/*regitster user cb for test*/

    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SC_OAM,SYS_WB_APPID_SC_OAM_SUBID_MAX, sys_usw_sc_oam_wb_sync), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_SPN_DMA_DROPM, sys_usw_sc_oam_isr_defect), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SC_OAM, SYS_WB_APPID_OAM_SUBID_MAX,sys_usw_sc_oam_wb_sync), ret, error_proc);
    #if defined E_UNIT && (FEATURE_MODE == 0)
    sys_usw_eunit_regitser_isr(lchip, SYS_EUNIT_ISR_G8031, sys_usw_aps_isr);
    #endif
    CTC_ERROR_RETURN(SYS_CB_REGISTER(lchip, SYS_CB_SCOAM_SET_CLIENT_SPEED, sys_usw_sc_oam_set_period));
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_sc_oam_wb_restore(lchip), ret, error_proc);
    }
    if (CTC_WB_ENABLE(lchip))
    {
        _sys_usw_sc_oam_wb_init(lchip);
    }
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SC_OAM, sys_usw_sc_oam_dump_db), ret, error_proc);

    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_SC_OAM);
    return CTC_E_NONE;
error_proc:

    if (NULL != g_sc_oam_master[lchip]->spool_ber)
    {
        ctc_spool_free(g_sc_oam_master[lchip]->spool_ber);
    }
    if (NULL != g_sc_oam_master[lchip]->spool_rei)
    {
        ctc_spool_free(g_sc_oam_master[lchip]->spool_rei);
    }

    if(0 != g_sc_oam_master[lchip]->opf_type)
    {
        sys_usw_opf_deinit(lchip, g_sc_oam_master[lchip]->opf_type);
    }

    if (NULL != g_sc_oam_master[lchip]->hash_mep)
    {
        ctc_hash_free(g_sc_oam_master[lchip]->hash_mep);
    }

    if (NULL != g_sc_oam_master[lchip]->p_cb_mutex)
    {
        sal_mutex_destroy(g_sc_oam_master[lchip]->p_cb_mutex);
        g_sc_oam_master[lchip]->p_cb_mutex = NULL;
    }

    if (NULL != g_sc_oam_master[lchip]->mutex)
    {
        sal_mutex_destroy(g_sc_oam_master[lchip]->mutex);
        g_sc_oam_master[lchip]->mutex = NULL;
    }
    if (NULL != g_sc_oam_master[lchip]->mep_defect_bitmap)
    {
        mem_free(g_sc_oam_master[lchip]->mep_defect_bitmap);
    }
    if (NULL != g_sc_oam_master[lchip])
    {
        mem_free(g_sc_oam_master[lchip]);
    }

    return ret;
}



int32
sys_usw_sc_oam_deinit(uint8 lchip)
{
    LCHIP_CHECK(lchip);
    if (NULL == g_sc_oam_master[lchip])
    {
        return CTC_E_NONE;
    }

    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_SCOAM_EVENT, NULL);
    sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_SC_OAM, NULL);

    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SC_OAM,0, NULL);
    sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_SPN_DMA_DROPM, NULL);
    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_OAM,0, NULL);
    #if defined E_UNIT && (FEATURE_MODE == 0)
    sys_usw_eunit_regitser_isr(lchip, SYS_EUNIT_ISR_G8031, NULL);
    #endif
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SC_OAM, NULL);

    ctc_hash_traverse(g_sc_oam_master[lchip]->hash_mep, (hash_traversal_fn)_sys_usw_sc_oam_db_free_node_data, NULL);
    ctc_hash_free(g_sc_oam_master[lchip]->hash_mep);
    ctc_spool_free(g_sc_oam_master[lchip]->spool_ber);
    ctc_spool_free(g_sc_oam_master[lchip]->spool_rei);
    sys_usw_opf_deinit(lchip, g_sc_oam_master[lchip]->opf_type);
    sal_mutex_destroy(g_sc_oam_master[lchip]->p_cb_mutex);
    sal_mutex_destroy(g_sc_oam_master[lchip]->mutex);
    mem_free(g_sc_oam_master[lchip]->mep_defect_bitmap);
    mem_free(g_sc_oam_master[lchip]);
    return CTC_E_NONE;
}

int32
sys_usw_sc_oam_show_status(uint8 lchip)
{
    uint16 i = 0;
    sys_sc_oam_mep_t* tmp_mep_db = NULL;
    uint32 w_path=0;
    uint32 p_path=0;
    uint32 a_path=0;
    g8031_aps_group_t* aps_group = NULL;
    char prot_type[32] = {0};
    char protection_path[16] = {"-"};
    char* req_sta[16] =
    {
        "NR",   /*0*/
        "DNR",  /*1*/
        "RR",   /*2*/
        "-",    /*3*/
        "EXER", /*4*/
        "WTR",  /*5*/
        "-",    /*6*/
        "MS",   /*7*/
        "-",    /*8*/
        "SD",   /*9*/
        "-",    /*10*/
        "SF",   /*11*/
        "-",    /*12*/
        "FS",   /*13*/
        "SF-P", /*14*/
        "LO"    /*15*/
    };

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_SC_OAM_INIT_CHECK(lchip);
    SE_OAM_LOCK(lchip);

    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----------------------------Overview----------------------------\n");
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "MEP Number     :%d/%d\n", g_sc_oam_master[lchip]->hash_mep->count, SYS_SC_CLIENT_ID_NUM);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "APS Grp Number :%d/%d\n", g_sc_oam_master[lchip]->aps_grp_cnt, SYS_APS_GRP_NUM);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "BER Number     :%d/16\n", g_sc_oam_master[lchip]->spool_ber->count);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "REI Number     :%d/16\n", g_sc_oam_master[lchip]->spool_rei->count);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "APS OPF Type   :%d\n", g_sc_oam_master[lchip]->opf_type);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "HW APS         :%d\n", g_sc_oam_master[lchip]->hw_aps);
    SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");

    if (g_sc_oam_master[lchip]->hash_mep->count)
    {
        sys_traverse_t user_data;
        sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
        user_data.value1 = 0;/*NO.*/
        user_data.value3 = lchip;
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------MEP Info-----------------------------\n");
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-6s%-14s%-8s%-8s%-8s%-8s%-6s%-8s\n", "NO.", "CLIENT","IDX", "SPEED", "MEP_EN", "PERIOD", "APS", "TX_EN");
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----------------------------------------------------------------\n");
        ctc_hash_traverse(g_sc_oam_master[lchip]->hash_mep, (hash_traversal_fn)_sys_usw_sc_oam_hash_traverse_cb, &user_data);
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    }

    if (g_sc_oam_master[lchip]->aps_grp_cnt)
    {
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------APS Info-----------------------------\n");
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-6s%-14s%-14s%-14s%-8s%-6s%-8s\n", "GRP", "WORK", "PROT", "ACTIVE", "REQ/STA", "WTR", "PROT_TYPE");
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----------------------------------------------------------------\n");
        for (i = 0; i <= SYS_APS_GRP_NUM; i++)
        {
            aps_group = &(g_sc_oam_master[lchip]->aps_group[i]);
            if (0 == aps_group->aps_grp_id)
            {
                continue;
            }
            prot_type[0] = '\0';
            if (aps_group->aps_channel)
            {
                sal_strcat(prot_type, "A");
            }
            if (!aps_group->bridge_permanent)
            {
                sal_strcat(prot_type, "B");
            }
            if (aps_group->direction)
            {
                sal_strcat(prot_type, "D");
            }
            if (aps_group->is_revertive)
            {
                sal_strcat(prot_type, "R");
            }
            tmp_mep_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip,aps_group->protection_path);
            if (!tmp_mep_db)
            {
                continue;
            }
            p_path = tmp_mep_db->client_id;
            if (1 == aps_group->protection_path_valid)
            {
                sal_sprintf(protection_path, "%u",p_path);
            }
            tmp_mep_db = _sys_usw_sc_oam_lkup_by_asic_client(lchip,aps_group->working_path);
             if (!tmp_mep_db)
             {
                 continue;
             }
             w_path = tmp_mep_db->client_id;
             a_path = (aps_group->active_path == aps_group->working_path)? w_path : p_path;

            SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-6d%-14u%-14s%-14u%-8s%-6d%-8s\n",
                       aps_group->aps_grp_id, w_path, protection_path, a_path,
                       req_sta[aps_group->current_state], aps_group->wtr_timer, prot_type);
        }
        SYS_SC_OAM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    }
    SE_OAM_UNLOCK(lchip);

    return CTC_E_NONE;
}


#endif
